从通过kerberos keytabs进行身份验证的Java应用程序在远程服务器上执行脚本

时间:2011-01-03 14:20:32

标签: java kerberos

这很可能早些时候得到了解答,但我所有的搜索都没有得到明确答案。我得到的是一个Java应用程序,它当前使用ssh密钥在远程计算机上运行脚本并保存结果。我正在使用keytabs将其更改为Kerberos身份验证。我已经设置了keytab并使用perl脚本对其进行了测试。如果有人能指出我告诉我如何在Java应用程序中使用kerberos keytabs的示例,那将非常有帮助。

谢谢, 基兰

1 个答案:

答案 0 :(得分:3)

这是在Java中使用keytab的完整实现。

import javax.security.auth.Subject;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.security.Principal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class SecurityUtils {
    public static class LoginConfig extends Configuration {
        private String keyTabLocation;
        private String servicePrincipalName;
        private boolean debug;

        public LoginConfig(String keyTabLocation, String servicePrincipalName, boolean debug) {
            this.keyTabLocation = keyTabLocation;
            this.servicePrincipalName = servicePrincipalName;
            this.debug = debug;
        }

        @Override
        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
            HashMap<String, String> options = new HashMap<String, String>();
            options.put("useKeyTab", "true");
            options.put("keyTab", this.keyTabLocation);
            options.put("principal", this.servicePrincipalName);
            options.put("storeKey", "true");
            options.put("doNotPrompt", "true");
            if (this.debug) {
                options.put("debug", "true");
            }
            options.put("isInitiator", "false");

            return new AppConfigurationEntry[]{new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options),};
        }
    }

    public static Subject loginAs(String keyTabLocation, String servicePrincipal) {
        try {
            LoginConfig loginConfig = new LoginConfig(keyTabLocation, servicePrincipal, true);
            Set<Principal> princ = new HashSet<Principal>(1);
            princ.add(new KerberosPrincipal(servicePrincipal));
            Subject sub = new Subject(false, princ, new HashSet<Object>(), new HashSet<Object>());
            LoginContext lc;
            lc = new LoginContext("", sub, null, loginConfig);
            lc.login();
            return lc.getSubject();
        } catch (LoginException e) {
            e.printStackTrace();
        }
        return null;
    }
}

loginAs方法将返回一个可用于执行特权操作的Subject:

result = Subject.doAs(subject,
        new PrivilegedExceptionAction<NamingEnumeration<SearchResult>>() {
            public NamingEnumeration<SearchResult> run() throws NamingException {
                return context.search(directoryBase, filterBuilder.toString(), searchCtls);
            }
        });