Java单点登录:针对Active Directory的Kerberos身份验证

15
我仍在尝试寻找一个基于Java的SSO解决方案(运行在*nix上),我可以在JBoss上使用它来授权访问Active Directory/域控制器。最初我尝试使用NTLM,但因为它不支持Windows Server >= 2008而放弃了。
因此,我正在尝试使用Kerberos来实现这一点,但似乎很难找到正确/可行的解决方案。请指导我如何设置此配置,如何验证Active Directory和/或域控制器以便:
1. 找出帐户是否有效 2. 获取用户的组列表
感谢任何帮助!
更新:
我正在使用jcifs-ext-0.9.4和jcifs-krb5-1.3.12来实现解决方案。我根据下面所述设置了web.xml:
<web-app>
  <!-- servlet / servlet-mapping / welcome-file-list skipped -->

 <filter>
 <filter-name>auth</filter-name>
 <filter-class>jcifs.http.AuthenticationFilter</filter-class>

 <init-param>
 <param-name>java.security.auth.login.config</param-name>
 <param-value>/WEB-INF/login.conf</param-value>
 </init-param>

 <init-param>
 <param-name>jcifs.spnego.servicePrincipal</param-name>
 <param-value>HTTP/testconn@mydomain.com</param-value>
 </init-param>

 <init-param>
 <param-name>jcifs.spnego.servicePassword</param-name>
 <param-value>supersecret</param-value>
 </init-param>

 <init-param>
 <param-name>sun.security.krb5.debug</param-name>
 <param-value>true</param-value>
 </init-param>

 <init-param>
 <param-name>java.security.krb5.realm</param-name>
 <param-value>mydomain.com</param-value>
 </init-param>

 <init-param>
 <param-name>java.security.krb5.kdc</param-name>
 <param-value>testdom01.mydomain.com </param-value>
 </init-param>

 <init-param>
 <param-name>jcifs.smb.client.domain</param-name>
 <param-value>TESTDOMAIN</param-value>
 </init-param>

 <init-param>
 <param-name>jcifs.http.enableNegotiate</param-name>
 <param-value>true</param-value>
 </init-param>

 <init-param>
 <param-name>jcifs.http.basicRealm</param-name>
 <param-value>mydomain.com</param-value>
 </init-param>

 <init-param>
 <param-name>jcifs.http.domainController</param-name>
 <param-value>testdom01.mydomain.com</param-value>
 </init-param>

 </filter>
 <filter-mapping>
 <filter-name>auth</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>
</web-app>

如果尝试访问该应用程序,则会导致以下堆栈跟踪:

2010-07-22 15:53:10,588 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/google].[default]] Servlet.service() for servlet default threw exception
java.lang.ArrayIndexOutOfBoundsException
        at java.lang.System.arraycopy(Native Method)
        at jcifs.ntlmssp.Type2Message.toByteArray(Type2Message.java:261)
        at jcifs.spnego.Authentication.processNtlm(Authentication.java:265)
        at jcifs.spnego.Authentication.process(Authentication.java:233)
        at jcifs.http.Negotiate.authenticate(Negotiate.java:46)
        at jcifs.http.AuthenticationFilter.doFilter(AuthenticationFilter.java:192)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
        at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
        at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
        at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
        at java.lang.Thread.run(Thread.java:619)

任何帮助都将受到欢迎。

5个回答

7
要完成此任务,您需要使用LDAP。幸运的是,Java对Kerberos和LDAP都有很好的支持。详细的步骤在http://java.sun.com/products/jndi/tutorial/ldap/security/gssapi.html上。步骤概述如下:
- 认证到Kerberos - 使用Kerberos扮演用户身份 - 执行GSSAPI绑定到Active Directory LDAP服务器 - 通过LDAP检索组列表

为什么这个被踩了?Kerberos 不包含用户组列表! - Borealid

1

你可以使用Waffle。它是免费的,支持Negotiate、NTLM和Kerberos。你还可以用它来检查用户的组列表。

"WAFFLE - Windows身份验证功能框架(轻量版)是一个本地的C#和Java库,可以处理Windows身份验证(Negotiate、NTLM和Kerberos)的所有事情。"


5
Waffle不幸地使用了win32 API,只能在Windows操作系统上运行。 - MrG

0
如果您想在您的机器上调试Kerberos、AD配置,那么您可以从以下链接下载应用程序。 https://github.com/shubham49/debugSSO 下载并在Weblogic服务器上部署该应用程序。 部署后打开主页,您将遇到不同的测试来调试配置。

0

我们使用Jespa来处理NTLM身份验证,我们已经在Solaris上测试了Tomcat和Glassfish,IE和Firefox都受支持,显然Chrome现在也支持NTLM。但是商业使用需要许可证,但我强烈推荐它。


对我来说,Jespa 的问题在于它假定使用 Java EE 和像 Play 这样的框架,使得我无法使用它。 - andyczerwonka

0

我开始撰写一篇文章,以探索Kerberos和JBoss的使用,计划是为初学者提供完整的指南,帮助他们设置和使用Kerberos与JBoss。我并不是说这是一个完整的答案,但如果您有问题,我可以尝试回答并将它们添加到博客中。

文章


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接