2014-05-02 61 views
1

我试图连线我们的Windows客户端应用程序以使用单点登录机制。我遵循可以找到的解释here。我已经无法实现第一步工作,即获得签名用户的票证授予票证。当运行我的单元测试(代码见下文),我收到以下异常:尽管allowtgtsessionkey注册表项无法检索TGT

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) 

这发生在我运行的Java 7的测试中,我认为,这意味着票据缓存为空。但是,当我使用Java 6运行测试时,登录成功,并且我可以从LoginContext中检索完全填充的Subject对象。在我读here时,Java 7现在完全尊重允许/拒绝导出TGT的Windows 7策略。所以我在注册表中设置了allowtgtsessionkey值,希望这能解决我的问题。但尽管已经重新登录并重新启动,但仍然无法通过Java 7访问我的TGT。使用Java 6时,它工作得很好。任何人都可以指出我错过了什么?

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 
} 
+0

你是一个本地机器管理员吗? –

+0

是的,我的帐户是本地管理员。 –

回答

2

看来,这是Windows的一个限制,当涉及到的账户也在地方行政部门。我阅读下列here

已知问题

如果一个AD帐户也被添加到本地管理员组 客户端PC,微软限制了这类客户端从获得门票的 会话密钥(即使您将allowtgtsessionkey 注册表项设置为1)。解决方法是:只要忘记您是用户登录的 ,请调用kinit.exe。不要依赖于LSA凭证缓存。

在最近的修复程序 ([35] http://support.microsoft.com/kb/942219/en-us,应包括在Vista SP1 ),这个限制被升高为正常
服务票证。但是,它仍然适用于TGT。由于Java使用TGT 来获取其他服务的门票(标准Kerberos进程),因此此更新对Windows上的JGSS编程没有任何好处。
此外,即使Java的实现更改为从LSA缓存中读取
服务票据,它仍然不能执行 委派,因为在这种情况下始终需要TGT。

+0

我不会接受这个答案,但是,如果任何人可能有解决方法。 –

+0

不幸的是,这*是答案。这是微软。我也患有他的PITA。唯一的选择是编写一个SSPI支持的JGSS实现。 –

+0

你能给SSPI提供任何参考/教程链接吗?我会将它们包含在我的答案中。 –