我正在尝试使用JAVA从Active Directory获取用于身份验证的TGT。

这是我的代码:

try
{
    URL localURL = super.getClass().getResource("jaas_ntlm_configuration.txt");
    System.setProperty("java.security.auth.login.config", localURL.toString());

    LoginContext localLoginContext = new LoginContext("GetLoginNameKerberos", new SampleCallbackHandler());

    localLoginContext.login();

    Subject localSubject = localLoginContext.getSubject();

    .....
}
catch (LoginException localLoginException) {
    localLoginException.printStackTrace();
}


此代码可在一台服务器上运行,但是在另一台服务器上,它在“ localLoginContext.login();”上失败。输出如下:

>>>KinitOptions cache name is C:\Users\x\krb5cc_x
LSA: Found Ticket
LSA: Made NewWeakGlobalRef
LSA: Found PrincipalName
LSA: Made NewWeakGlobalRef
LSA: Found DerValue
LSA: Made NewWeakGlobalRef
LSA: Found EncryptionKey
LSA: Made NewWeakGlobalRef
LSA: Found TicketFlags
LSA: Made NewWeakGlobalRef
LSA: Found KerberosTime
LSA: Made NewWeakGlobalRef
LSA: Found String
LSA: Made NewWeakGlobalRef
LSA: Found DerValue constructor
LSA: Found Ticket constructor
LSA: Found PrincipalName constructor
LSA: Found EncryptionKey constructor
LSA: Found TicketFlags constructor
LSA: Found KerberosTime constructor
LSA: Finished OnLoad processing
>> Acquire default native Credentials
LSA: Found KrbCreds constructor
LSA: Got handle to Kerberos package
LSA: Response size is 1556
LSA: Principal domain is SUB.DOMAIN.COM
LSA: Name type is 1
LSA: Name count is 1
LSA: Principal domain is SUB.DOMAIN.COM
LSA: Name type is 2
LSA: Name count is 2
LSA: Session key all zero. Stop.
>>> Found no TGT's in LSA
javax.security.auth.login.LoginException: Unable to obtain Princpal Name for authentication
    at com.sun.security.auth.module.Krb5LoginModule.promptForName(Unknown Source)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Unknown Source)
    at com.sun.security.auth.module.Krb5LoginModule.login(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at javax.security.auth.login.LoginContext.invoke(Unknown Source)
    at javax.security.auth.login.LoginContext.access$000(Unknown Source)
    at javax.security.auth.login.LoginContext$4.run(Unknown Source)
    at javax.security.auth.login.LoginContext$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
    at javax.security.auth.login.LoginContext.login(Unknown Source)
    at my.test.MyTest.main(MyTest.java:123)


您能帮我了解问题所在吗?

谢谢。

最佳答案

如果您不希望输入用户名(您希望“单一登录”),那么您的问题就是一个已知问题:LSA API不会移交TGT的会话密钥,因为这被认为是安全漏洞。该错误消息清楚地表明这正是发生的情况。

有一个Windows注册表项AllowTGTSessionKey,您可以将其设置为true以禁用此限制,但是此设置是针对每个工作站而不是针对每个服务器的,因此尚不清楚这是为什么它可以在一个工作站上运行的原因放在另一边。如果我没有记错的话,另一个原因可能是使用Windows版本,因为它是随XP Service Pack 2一起引入的。

在Java中实现单点登录的正确方法是将TGT的处理委托给Windows SSPI,后者是类似于GSS-API的更高级别的API。有一个很好的库可以为您完成此任务,我个人可以建议您:WAFFLE。

09-25 20:43