我正在尝试使用 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 的 session key ,因为这被认为是一个安全漏洞。错误消息清楚地表明这正是发生的情况。
有一个 Windows 注册表项,AllowTGTSessionKey
,您可以将其设置为 true 以禁用此限制,但此设置是针对每个工作站而不是针对每个服务器的,因此不清楚这是否就是它在一个地方而不在另一个地方起作用的原因。另一个原因可能是使用的 Windows 版本,因为如果我没记错的话,这是随 XP Service Pack 2 引入的。
在 Java 中实现单点登录的正确方法是将 TGT 的处理委托(delegate)给 Windows SSPI,一个类似于 GSS-API 的高级 API。有一个很好的库可以为您做这件事,我个人可以推荐它:WAFFLE。
关于java - 无法从 AD 获取 TGT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13630477/