javax.naming.AuthenticationException

javax.naming.AuthenticationException,java,active-directory,ldap,kerberos,gssapi,Java,Active Directory,Ldap,Kerberos,Gssapi,我正在尝试使用我的windows凭据和NTLM为ActiveDirectory创建上下文(客户端和服务器都是windows) 这是我的代码: public void func() { try { URL configURL = getClass().getResource("jaas_ntlm_configuration.txt"); System.setProperty("java.security.auth.login.config", configURL

我正在尝试使用我的windows凭据和NTLM为ActiveDirectory创建上下文(客户端和服务器都是windows)

这是我的代码:

public void func() {
    try {
      URL configURL = getClass().getResource("jaas_ntlm_configuration.txt");
        System.setProperty("java.security.auth.login.config", configURL.toString());

        // If the application is run on NT rather than Unix, use this name
        String loginAppName = "MyConfig";

        // Create login context
        LoginContext lc = new LoginContext(loginAppName, new SampleCallbackHandler());

        // Retrieve the information on the logged-in user
        lc.login();

        // Get the authenticated subject
        Subject subject = lc.getSubject();

        System.out.println(subject.toString());

        Subject.doAs(subject, new JndiAction(new String[] { "" }));
    }
    catch (LoginException e) {
      e.printStackTrace();
    }
}

class JndiAction implements java.security.PrivilegedAction {
    private String[] args;

    public JndiAction(String[] origArgs) {
        this.args = (String[])origArgs.clone();
    }

    public Object run() {
        performJndiOperation(args);
        return null;
    }

    private static void performJndiOperation(String[] args) {

        // Set up environment for creating initial context
        Hashtable env = new Hashtable(11);

        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

        // Must use fully qualified hostname
        env.put(Context.PROVIDER_URL, "ldap://server:389");

        // Request the use of the "GSSAPI" SASL mechanism
        // Authenticate by using already established Kerberos credentials
        env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");

        try {
            /* Create initial context */
//          DirContext ctx = new InitialDirContext(env);

              // Create the initial context
            DirContext ctx = new InitialLdapContext(env, null);


            // Close the context when we're done
            ctx.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
}
我的jaas_ntlm_configuration.txt文件包含:

MyConfig { com.sun.security.auth.module.Krb5LoginModule required
useTicketCache=true
doNotPrompt=false;
};
当我尝试启动上下文时,会出现以下异常:

javax.naming.AuthenticationException: GSSAPI [Root exception is javax.security.sasl.SaslException: Final handshake failed [Caused by GSSException: Token had invalid integrity check (Mechanism level: Corrupt checksum in Wrap token)]]
        at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(Unknown Source)
        at com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
        at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
        at com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
        at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
        at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
        at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
        at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
        at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
        at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
        at javax.naming.InitialContext.init(Unknown Source)
        at javax.naming.ldap.InitialLdapContext.<init>(Unknown Source)
        at JndiAction.performJndiOperation(JndiAction.java:204)
        at JndiAction.run(JndiAction.java:181)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Unknown Source)
        at MyTest.Do(MyTest.java:59)
        at MyTest.main(MyTest.java:68)
Caused by: javax.security.sasl.SaslException: Final handshake failed [Caused by GSSException: Token had invalid integrity check (Mechanism level: Corrupt checksum in Wrap token)]
        at com.sun.security.sasl.gsskerb.GssKrb5Client.doFinalHandshake(Unknown Source)
        at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source)
        ... 18 more
Caused by: GSSException: Token had invalid integrity check (Mechanism level: Corrupt checksum in Wrap token)
        at sun.security.jgss.krb5.WrapToken_v2.getData(Unknown Source)
        at sun.security.jgss.krb5.WrapToken_v2.getData(Unknown Source)
        at sun.security.jgss.krb5.Krb5Context.unwrap(Unknown Source)
        at sun.security.jgss.GSSContextImpl.unwrap(Unknown Source)
        ... 20 more
javax.naming.AuthenticationException:GSSAPI[根异常为javax.security.sasl.SaslException:最终握手失败[由GSSException引起:令牌具有无效的完整性检查(机制级别:包装令牌中的校验和损坏)]]
位于com.sun.jndi.ldap.sasl.LdapSasl.saslBind(未知源)
位于com.sun.jndi.ldap.LdapClient.authenticate(未知源)
位于com.sun.jndi.ldap.LdapCtx.connect(未知源)
位于com.sun.jndi.ldap.LdapCtx。(未知来源)
位于com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(未知源)
位于com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(未知源)
位于com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(未知源)
位于com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(未知源)
位于javax.naming.spi.NamingManager.getInitialContext(未知源)
位于javax.naming.InitialContext.getDefaultInitCtx(未知源)
位于javax.naming.InitialContext.init(未知源)
位于javax.naming.ldap.InitialLdapContext。(未知源)
在jndiation.performJndiOperation(jndiation.java:204)
运行(jndiation.java:181)
位于java.security.AccessController.doPrivileged(本机方法)
位于javax.security.auth.Subject.doAs(未知源)
在MyTest.Do(MyTest.java:59)
位于MyTest.main(MyTest.java:68)
原因:javax.security.sasl.SaslException:最终握手失败[原因:GSSException:令牌的完整性检查无效(机制级别:包装令牌中的校验和损坏)]
位于com.sun.security.sasl.gsskerb.GssKrb5Client.doFinalHandshake(未知来源)
位于com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(未知来源)
... 还有18个
原因:GSSExException:令牌的完整性检查无效(机制级别:包装令牌中的校验和损坏)
位于sun.security.jgss.krb5.WrapToken_v2.getData(未知源)
位于sun.security.jgss.krb5.WrapToken_v2.getData(未知源)
位于sun.security.jgss.krb5.Krb5Context.unwrap(未知源)
位于sun.security.jgss.GSSContextImpl.unwrap(未知源)
... 20多

有人能帮我解决这个问题吗?

您实际上正在使用Kerberos身份验证。。 如果这就是你想要做的,我可以告诉你我是如何让它工作的:

- add somewhere a file called krb5.conf with inside :

[libdefaults]
default_realm = YOUR_REALM
default_tkt_enctypes = arcfour-hmac-md5
default_tgs_enctypes = arcfour-hmac-md5
permitted_enctypes = arcfour-hmac-md5

dns_lookup_kdc = true
dns_lookup_realm = false

[realms]
YOUR_REALM = {
kdc = KERBEROS_SERVER
default_domain = YOUR_REALM
}
  • 将以下行添加到代码中:

    setProperty(“java.security.krb5.conf”,指向KRB5CONF文件的路径); System.setProperty(“sun.security.krb5.principal”,principal\u NAME\u,不含域)

如果您不了解Kerberos服务器,则无法从命令行启动klist,并获取使用LDAP协议(LDAP)的服务/server@domain->服务器)

如果仍然不起作用,请尝试添加

System.setProperty("sun.security.krb5.debug", "true"); 

并发布输出。

这看起来像Kerberos而不是NTLM—您是否尝试过类似Tagish库的方法—它会进行本机调用以根据NTML进行身份验证: