Java SSO: Kerberos authentication against Active Directory

27,346

Solution 1

To do this, you actually need to use LDAP. Luckily for you, Java has solid support for both Kerberos and LDAP. The detailed procedure is at http://java.sun.com/products/jndi/tutorial/ldap/security/gssapi.html .

Overview of steps:

  • Authenticate to Kerberos
  • Use Kerberos to assume user identity
  • Perform GSSAPI bind to Active Directory LDAP server
  • Retrieve group list over LDAP

Solution 2

You can use Waffle. It's free and supports Negotiate, NTLM and Kerberos. You can also check the group list of the user with it.

"WAFFLE - Windows Authentication Functional Framework (Light Edition) is a native C# and Java library that does everything Windows authentication (Negotiate, NTLM and Kerberos)."

Share:
27,346
Ashraf Tawfeeq
Author by

Ashraf Tawfeeq

Updated on October 30, 2020

Comments

  • Ashraf Tawfeeq
    Ashraf Tawfeeq over 3 years

    I'm still trying to find a Java based solution for SSO (running on *nix), which I can use on JBoss to authorize against an Active Directory/domain controller. I initially tried to do this via NTLM, but gave up because it will be not supported on Windows Server >= 2008.

    Therefore I'm trying to implement this using Kerberos, but it seems impossible to find a correct/working solution. Please point me in the right direction explaining how to set up such a configuration, how to validate against the Active Directory and/or domain controller in order to:

    1. find out if the account is valid and
    2. fetch the group list of the user

    Any help is appreciated!


    UPDATE

    I'm working on a solution using jcifs-ext-0.9.4 and jcifs-krb5-1.3.12. I set up the web.xml as described below:

    <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/[email protected]</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>
    

    This leads to the following stacktrace if trying to access the 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)
    

    Any help is appreciated.