J'essaie d'installer SSO pour une application Web Java à l'aide de Kerberos/SpNego. J'utilise:
Après avoir surmonté le problème décrit dans Comment configurer Kerberos sur un serveur Tomcat/Linux? , je suis maintenant coincé avec l'erreur suivante:
org.springframework.security.authentication.BadCredentialsException: Kerberos validation not succesful
at org.springframework.security.kerberos.authentication.Sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.Java:70) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider.authenticate(KerberosServiceAuthenticationProvider.Java:64) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.Java:156) ~[spring-security-core-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter.doFilter(SpnegoAuthenticationProcessingFilter.Java:145) ~[spring-security-kerberos-web-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.Java:199) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.Java:110) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.Java:50) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:87) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:192) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:160) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.Java:344) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.Java:261) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:241) [catalina.jar:7.0.55]
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208) [catalina.jar:7.0.55]
at org.lightadmin.core.view.TilesContainerEnrichmentFilter.doFilterInternal(TilesContainerEnrichmentFilter.Java:40) [lightadmin-1.2.0.RC1.jar:1.2.0.RC1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:241) [catalina.jar:7.0.55]
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208) [catalina.jar:7.0.55]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.Java:77) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:241) [catalina.jar:7.0.55]
at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208) [catalina.jar:7.0.55]
at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:220) [catalina.jar:7.0.55]
at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:122) [catalina.jar:7.0.55]
at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:501) [catalina.jar:7.0.55]
at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:171) [catalina.jar:7.0.55]
at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:103) [catalina.jar:7.0.55]
at org.Apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.Java:950) [catalina.jar:7.0.55]
at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:116) [catalina.jar:7.0.55]
at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:408) [catalina.jar:7.0.55]
at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:1070) [Tomcat-coyote.jar:7.0.55]
at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:611) [Tomcat-coyote.jar:7.0.55]
at org.Apache.Tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.Java:316) [Tomcat-coyote.jar:7.0.55]
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145) [na:1.7.0_67]
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615) [na:1.7.0_67]
at org.Apache.Tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.Java:61) [Tomcat-coyote.jar:7.0.55]
at Java.lang.Thread.run(Thread.Java:745) [na:1.7.0_67]
Caused by: Java.security.PrivilegedActionException: null
at Java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_67]
at javax.security.auth.Subject.doAs(Subject.Java:415) ~[na:1.7.0_67]
at org.springframework.security.kerberos.authentication.Sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.Java:67) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
... 42 common frames omitted
Caused by: org.ietf.jgss.GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - RC4 with HMAC)
at Sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.Java:788) ~[na:1.7.0_67]
at Sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.Java:342) ~[na:1.7.0_67]
at Sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.Java:285) ~[na:1.7.0_67]
at Sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.Java:875) ~[na:1.7.0_67]
at Sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.Java:548) ~[na:1.7.0_67]
at Sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.Java:342) ~[na:1.7.0_67]
at Sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.Java:285) ~[na:1.7.0_67]
at org.springframework.security.kerberos.authentication.Sun.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.Java:162) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.kerberos.authentication.Sun.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.Java:152) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
... 45 common frames omitted
Caused by: Sun.security.krb5.KrbException: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - RC4 with HMAC
at Sun.security.krb5.KrbApReq.authenticate(KrbApReq.Java:273) ~[na:1.7.0_67]
at Sun.security.krb5.KrbApReq.<init>(KrbApReq.Java:144) ~[na:1.7.0_67]
at Sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.Java:108) ~[na:1.7.0_67]
at Sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.Java:771) ~[na:1.7.0_67]
... 53 common frames omitted
Cependant, il semble que la clé devrait être là, car au démarrage de l'application, j'ai eu le débogage suivant:
Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is /opt/pksvc/Tomcat_edl/current/conf/TestSpnego.keytab refreshKrb5Config is false principal is [email protected] tryFirstPass is false useFirstPass is false storePass is false clearPass is false
principal is [email protected]
Will use keytab
>>> KeyTabInputStream, readName(): MYREALM.DE
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): lxdetstpksvc01.mydomain.de
>>> KeyTab: load() entry length: 83; type: 23
Ordering keys wrt default_tkt_enctypes list
Java config name: /opt/pksvc/Tomcat_edl/current/conf/krb5.conf
Loaded from Java config
default etypes for default_tkt_enctypes: 23.
Commit Succeeded
Donc enctype 23 = RC4 avec HMAC est le type de l'entrée KeyTab et le type enctype par défaut . Je peux également voir que le navigateur envoie un jeton avec ce type enctype (j'ai supprimé la partie binaire de ce qui suit):
Ticket TicketType{TktVno=5,Realm=MYREALM.DE,Sname=HTTP/lxdetstpksvc01.mydomain.de,EncPart=EncryptedData{Etype=23,Kvno=4,Cipher=binary[... 352 16728 KerberosV5.TicketType
Authenticator EncryptedData{Etype=23,Kvno=nothing,Cipher=binary[... 17080 2872 KerberosV5.EncryptedData
Donc tout semble être encytpe 23 (RC4 avec HMAC). Lorsque j’ai jeté un coup d’œil au code, j’ai trouvé que Sun.security.krb5.EncryptionKey, utilisé par KrbApReq (qui renvoie l’erreur dans la pile ci-dessus), est en fait non seulement une comparaison du type d’enct, mais également de la version. Donc, je suppose que c'est ce qui doit être faux dans mon cas. Dans le ticket ci-dessus, Kvno = 4 pour EncryptedData et pour Authenticator EncryptedData, il s'agit de Kvno = rien. Ceux-ci devraient-ils correspondre?
Comment puis-je résoudre ça? Est-ce que cela est influencé par la génération du keytab?
Il s’est avéré que l’erreur ci-dessus résultait de deux problèmes:
Le service principal dans la configuration de printemps était faux. C'é[email protected], mais HTTP/[email protected] est correct.
Le Kvno dans le clavier n'était pas identique au Kvno stocké dans le Active Directory. Comme indiqué à la page suivante, __. https://Tomcat.Apache.org/Tomcat-7.0-doc/windows-auth-howto.html Active Directory élève le Kvno à chaque exécution de ktpass ..__ Cependant, je n'ai pas pu trouver la valeur (msDS-KeyVersionNumber) pourit dans notre AD et je ne pouvais le saisir qu'à partir de la requête.
Résumé de l'erreur "Impossible de trouver la clé du type approprié à déchiffrer ..." peut résulter de l'un des problèmes suivants:
Nous avons également eu une erreur Invalid argument (400) - Cannot find key of appropriate type to decrypt ...
.
Cela peut simplement être jeté si le chemin d'accès au keytab est faux (dans notre cas, nous avons oublié que nous avions un mappage de volume dans le menu fixe).
Assurez-vous donc que le chemin d'accès au clavier est le bon chemin, car cela pourrait déclencher cette exception bizarre.
Cela peut également être levé si vous utilisez Active Directory en tant que KDC et l'utilisateur keytab est configuré pour un paramètre de cryptage différent de celui utilisé par votre keytab. Dans mon cas, AES 128 a été configuré et je m'attendais à AES 256. Un simple changement de configuration dans AD a résolu le problème.