Moin!
My attempts to authenticate a user via SSO with Spring Security 5 and Kerberos fail due to an exception from deep in the Kerberos code. I will first show the stack trace and the code causing it and then give additional information about my environment which might help to eliminate some possibilities.
Stack trace
WARN 3932 --- [apr-8080-exec-1] w.a.SpnegoAuthenticationProcessingFilter : Negotiate Header was invalid: Negotiate YIILSwYGKwYBBQUCoIILPzCCCzugMDAuBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCN[and so on]
org.springframework.security.authentication.BadCredentialsException: Kerberos validation not successful
at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:71) ~[spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
at org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider.authenticate(KerberosServiceAuthenticationProvider.java:64) ~[spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.1.1.RELEASE.jar:5.1.1.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-5.1.1.RELEASE.jar:5.1.1.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:512) ~[spring-security-config-5.1.1.RELEASE.jar:5.1.1.RELEASE]
...
Caused by: java.security.PrivilegedActionException: null
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_162]
at javax.security.auth.Subject.doAs(Subject.java:422) ~[na:1.8.0_162]
at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:68) ~[spring-security-kerberos-core-1.0.1.RELEASE.jar:1.0.1.RELEASE]
...
Caused by: org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos credentails)
at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:87) ~[na:1.8.0_162]
at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:127) ~[na:1.8.0_162]
at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:198) ~[na:1.8.0_162]
So there is a
BadCredentialsException
while mySunJaasKerberosTicketValidator
is validating the SSO Ticket. This is just rethrowing aPrivilegedActionException
coming frompublic KerberosTicketValidation validateTicket(byte[] token) { try { return Subject.doAs(this.serviceSubject, new KerberosValidateAction(token)); } catch (PrivilegedActionException e) { throw new BadCredentialsException("Kerberos validation not successful", e); }
}
The
PrivilegedActionException
is hard to track as it comes from anative
methodjava.security.AccessController.doPrivileged
. I don't know the implementation. What I find interesting is that thePrivilegedActionException
prints out asCaused by: java.security.PrivilegedActionException: null
The
PrivilegedActionException.toString
method ispublic String toString() { String s = getClass().getName(); return (exception != null) ? (s + ": " + exception.toString()) : s; }
So the
exception
(the cause exception) is not null but it prints out asnull
...However The stack trace tells us that the root of the problem is a
GSSException
coming from the class Krb5AcceptCredential.if (creds == null) throw new GSSException(GSSException.NO_CRED, -1,"Failed to find any Kerberos credentails");
And
creds == null
is becauseKrb5Util.getServiceCreds
(see implementation) returnsnull
without causing an exception.
This is how far I got until now. Now some additional information.
Creating the Ticket Validator in my WebSecurityConfig
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
ticketValidator.setServicePrincipal("HTTP/host@REALM");
FileSystemResource fs = new FileSystemResource("PATH_TO_KEYTAB");
ticketValidator.setKeyTabLocation(fs);
LOGGER.info(fs.exists()); // prints 'true'
Creating the KerberosServiceAuthenticationProvider
This is the configuration of the object which will throw BadCredentialsException
.
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(sunJaasKerberosTicketValidator());
provider.setUserDetailsService(myUserDetailService);
provider.supports(KerberosServiceRequestToken.class);
I know SSO works
I have the luxury of being able to proof that the SSO infrastructor of my company works. The same server is running another app (Spring Security 4 with Kerberos) where a user can be successfully authenticated via SSO. So there is most likely something wrong with my setup.
I use Chrome by the way, but I also tested it with IE.
If you need additional information from my WebSecurityConfig
or something else I will provide it. May the force be with you :-)
Other questions
This is what I found so far but these examples are slightly different.
- GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
- Other error message
- Other setup: I don't have a krb5.conf file
- BadCredentialsException: Kerberos validation not succesfull
- Other root exception causing the
BadCredentialsException
- From 2012
- Other root exception causing the
- Kerberos authentication not working with spring security
- Other root exception causing the
BadCredentialsException
- Other root exception causing the