问题
I'm trying to wire our windows client application to use a single-sign-on mechanism. I'm following the explanations that can be found here. I'm already having trouble getting the first step to work, that is, acquiring the Signed On User's Ticket-Granting-Ticket. When running my unit test (code see below), I'm getting the following exception:
javax.security.auth.login.LoginException: Unable to obtain Princpal Name for authentication
at com.sun.security.auth.module.Krb5LoginModule.promptForName(Krb5LoginModule.java:800)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:671)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:584)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:784)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:203)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:698)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:696)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:695)
at javax.security.auth.login.LoginContext.login(LoginContext.java:594)
at org.myapp.test.cases.SSOTest.testSSO(SSOTest.java:28)
This happens when I run the test with Java 7. I thought this means that the ticket cache is empty. However, when I run the test with Java 6, the login is successful, and I can retrieve a fully populated Subject
object from the LoginContext
. As I read here, Java 7 now fully respects the Windows 7 policies which allow/deny exporting TGTs. So I set the the allowtgtsessionkey
value in my registry, hoping this would fix my problem. But despite having relogged and restarted, I still can't access my TGT with Java 7. With Java 6, it works just fine. Could anyone point out what I'm missing?
SSOTest.java:
@Test
public void testSSO() {
System.setProperty("java.security.auth.login.config", "D:\\login.conf");
LoginContext lc = null;
try {
lc = new LoginContext("TestLoginContext1");
} catch (LoginException e1) {
e1.printStackTrace();
}
try {
lc.login(); // Exception happens here
} catch (LoginException e) {
e.printStackTrace();
}
Subject signedOnUserSubject = lc.getSubject();
System.out.println(signedOnUserSubject);
}
login.conf
TestLoginContext1 {
com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true doNotPrompt=true debug=true;
};
krb5.conf
[libdefaults]
default_realm = MY.DOMAIN.COM
[realms]
MY.DOMAIN.COM = {
kdc = domaincontroller.my.domain.com
admin_server = domaincontroller.my.domain.com
default_domain = MY.DOMAIN.COM
}
回答1:
It seems this is a limitation of Windows when it comes to accounts that are also in the local administration group. I read the following here:
Known Issues
If an AD account is also added into local administrator group on the client PC, Microsoft restricts such client from getting the session key for tickets (even if you set the allowtgtsessionkey registry key to 1). The workaround is: Just forget you're a logged in user, call kinit.exe. Do not depends on LSA credential cache.
In a recent hotfix ([35]http://support.microsoft.com/kb/942219/en-us, should be included in Vista SP1), this restriction is lifted for normal
service tickets. However, it still applies to TGT. Since Java uses TGT to acquire tickets for other services (the standard Kerberos process), this update provides no benefit to JGSS programming on Windows.
Furthermore, even if the implementation of Java is changed to read
service tickets from the LSA cache, it still cannot perform delegation, since a TGT is always needed in that case.
来源:https://stackoverflow.com/questions/23427343/cannot-retrieve-tgt-despite-allowtgtsessionkey-registry-entry