https://issues.apache.org/bugzilla/show_bug.cgi?id=57022

            Bug ID: 57022
           Summary: Tomcat Spnego authentication against Active Directory
                    fails with Java 8
           Product: Tomcat 7
           Version: 7.0.55
          Hardware: PC
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: detelinyorda...@gmail.com

Created attachment 32059
  --> https://issues.apache.org/bugzilla/attachment.cgi?id=32059&action=edit
Tomcat JAAS configuration

Hello everyone,
   I'm successfully using Tomcat 7.0.55 configured with Spnego authentication
against Active Directory running Windows 2008 Server and Java 1.7.0.51. 
After switching to Java 1.8.0_20, authentication does not work anymore, Tomcat
logs the following error message:

SEVERE: Exception performing authentication
javax.naming.AuthenticationException: GSSAPI [Root exception is
javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException:
No valid credentials provided (
Mechanism level: Failed to find any Kerberos tgt)]]; remaining name
'CN=Users,DC=example,DC=com'
        at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(LdapSasl.java:169)
        at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:236)
        at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2788)
        at com.sun.jndi.ldap.LdapCtx.ensureOpen(LdapCtx.java:2696)
        at com.sun.jndi.ldap.LdapCtx.ensureOpen(LdapCtx.java:2670)
        at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1941)
        at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1844)
        at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1769)
        at
com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:392)
        at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:358)
        at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:341)
        at
javax.naming.directory.InitialDirContext.search(InitialDirContext.java:267)
        at
org.apache.catalina.realm.JNDIRealm.getUserBySearch(JNDIRealm.java:1446)
        at org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:1297)
        at org.apache.catalina.realm.JNDIRealm.getUser(JNDIRealm.java:1233)
        at
org.apache.catalina.realm.JNDIRealm.getPrincipal(JNDIRealm.java:2049)
        at
org.apache.catalina.realm.JNDIRealm.getPrincipal(JNDIRealm.java:1965)
        at org.apache.catalina.realm.RealmBase.authenticate(RealmBase.java:513)
        at
org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:309)
        at
org.apache.catalina.realm.LockOutRealm.authenticate(LockOutRealm.java:249)
        at
org.apache.catalina.authenticator.SpnegoAuthenticator.authenticate(SpnegoAuthenticator.java:255)

Tomcat is configured according to the "Windows Authentication How-To" document,
I'm attaching the krb5.ini, jaas.conf and server.xml that contains the
JNDIRealm definition.

I have investigated the problem and I believe it is related to the Kerberos
constraint delegation support added in Java 8, see:

http://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/jgss-features.html
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6355584

It seems that per default, GSS API in Java 8 will attempt constraint delegation
on the acceptor side, see referenced changes and in particular the
getCredDelegState() method:
http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/a1bbb8805e22

The result of this, is that Tomcat's JNDIRealm now finds the delegated
credential delivered with the constraint delegation and switches GSSAPI
security mechanism for JNDI/LDAP (this was not the case on Java 7). However,
the Kerberos initiation during LDAP authentication does not find the Kerberos
TGT in the Subject. After digging further, I noticed that the Subject used
during the LDAP authentication is not set. Though the SpnegoAuthenticator
initializes a Subject instance using Kerberos login via JAAS and this contains
the obtained TGT, this Subject instance is not used for performing the LDAP
authentication. I saw the following comment in JNDIRealm.getPrincipal:

// Note: Subject already set in SPNEGO authenticator so no need for
Subject.doAs() here

So I decided to modify this and execute the getPrincipal using Subject.doAs()
and the Subject instance available after the Kerberos login. This lead to
successful authentication to LDAP and I was able to access the Spnego-secured
webapp again.

Please note that this setup is not using any file-system Kerberos credential
cache, so it requires that the Kerberos TGT is available in the Subject
instance associated with current ACC.

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to