mugua mugua - 14 days ago 9
Java Question

Spring Security Kerberos, Kerberos + AD - Error: Access Denied, No key to store

This is from Kerberos sample app found at https://github.com/spring-projects/spring-security-kerberos/tree/master/spring-security-kerberos-samples/sec-server-win-auth corresponding to http://docs.spring.io/spring-security-kerberos/docs/1.0.1.RELEASE/reference/htmlsingle/#samples-sec-server-win-auth.

All I’m doing is modifying the src/main/resources/application.yml to fit my system and going back and forth between creating SPNs and Keytab files.
My spring application seems to be starting fine. Below is the Kerberos config that comes through the console output.


Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is /etc/client-server.keytab refreshKrb5Config is false principal is HTTP/client-server.example.org@REALM tryFirstPass is false useFirstPass is false storePass is false clearPass is false

principal is HTTP/client-server.example.org@REALM

Will use keytab

Commit Succeeded


So I can see that the client app has accepted my settings so far. Then I try to access client-server:8080/hello through chrome on another machine. The first error I get is Acces is denied (user is anonymous). Which is supposed to redirect to the authentication entry point. Then I get the following, ending with “No key to store”


[nio-8080-exec-4] w.a.SpnegoAuthenticationProcessingFilter : Received Negotiate Header for request client-server:8080/favicon.ico: Negotiate YIIHZAYGKwYBBQUCoIIHWDCCB1SgMDAuBgk……./9AdsoFH2ya7C

[nio-8080-exec-4] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider

[nio-8080-exec-4] .a.KerberosServiceAuthenticationProvider : Try to validate Kerberos Token

[nio-8080-exec-4] .a.KerberosServiceAuthenticationProvider : Succesfully validated myUsername@REALM

[nio-8080-exec-4] o.s.s.l.s.FilterBasedLdapUserSearch : Searching for user 'myUsername@REALM', with user search [ searchFilter: '', searchBase: 'DC=xxxxx', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]

Debug is true storeKey true useTicketCache true useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is HTTP/client-server.example.org@REALM tryFirstPass is false useFirstPass is false storePass is false clearPass is false

Acquire TGT from Cache

Principal is HTTP/client-server.example.org@REALM

2015-11-27 11:38:47.906 DEBUG 3183 --- [nio-8080-exec-4] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2015-11-27 11:38:47.906 DEBUG 3183 --- [nio-8080-exec-4] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2015-11-27 11:38:47.912 ERROR 3183 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.ldap.AuthenticationException: No key to store; nested exception is javax.naming.AuthenticationException: No key to store [Root exception is javax.security.auth.login.LoginException: No key to store]


Now it appears that the app is able to validate my user, but I have no idea if it could find my user info.
Viewing the source for Krb5LoginModule.java at cr.openjdk.java.net/~weijun/7201053/webrev.00/raw_files/new/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java, you can find the login exception, no key to store, by simple search. The code says that my ktab (keytab I’m guessing), is null. Strangely enough, the console output does say that when I try to navigate using the browser, that the keytab is null, even though it wasn’t when I started up the application.

Does anyone know why my keytab is going null when I have a user try to access my application? Or is something else wrong with my application or system configuration?

Answer

So I slept on this for the weekend. Strangely enough, it looked like the solution now works since the TGT acquired from cache was past renewal time. I don’t really know how it all works, but now the keytab is accepted when my user navigates to the application.
The only problem left was the Ldap couldn’t find my user details due to a mismatch between the Kerberos username used to query LDAP, so I had to re-implement org.springframework.security.ldap.search.FilterBasedLdapUserSearch to modify the username. Then the solution worked.