2

我正在尝试使用 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)

你能帮我理解是什么问题吗?

谢谢。

4

1 回答 1

6

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

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

在 Java 中实现单点登录的正确方法是将 TGT 的处理委托给 Windows SSPI,这是一个类似于 GSS-API 的更高级别的 API。有一个很好的图书馆可以为你做这件事,我个人可以推荐:WAFFLE。

于 2012-11-29T18:28:37.147 回答