title: Spring Authorization Server + Kerberos?
body: <p>Has anybody seen the new Spring Authorization Server (0.3.1) + Kerberos (with a keytab) working together? I've seen that Kerb4J needs to be used now instead of spring-security-kerberos (see <a href="https://github.com/spring-projects/spring-security-kerberos/issues/160" rel="nofollow noreferrer">https://github.com/spring-projects/spring-security-kerberos/issues/160</a>) I've got a Spring Authorization Server, Resource Server, and Login/Client SecurityConfig. Here's my code in a nutshell</p>
  <pre><code>    @Bean
      public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
          KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
          provider.setUserDetailsService(userDetailsService());
          return provider;
      }
      
      @Bean
      public SpnegoAuthenticationProvider kerberosServiceAuthenticationProvider() {
          SpnegoAuthenticationProvider provider = new SpnegoAuthenticationProvider();
          provider.setTicketValidator(sunJaasKerberosTicketValidator());
          provider.setExtractGroupsUserDetailsService(new ExtractGroupsUserDetailsService());
          provider.setServerSpn(servicePrincipal);
          return provider;
      }
      
      @Bean
      public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
          SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
          ticketValidator.setServicePrincipal(servicePrincipal);
          ticketValidator.setKeyTabLocation(resourceLoader.getResource(keytabLocation));
          return ticketValidator;
      }
  
          @Bean
          public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(SimpleUrlAuthenticationFailureHandler kerberosAuthenticationFailureHandler,
                                                                                           AuthenticationManager oauth2AuthenticationManager) {
              SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
              filter.setAuthenticationManager(oauth2AuthenticationManager);
              filter.setAuthenticationFailureHandler(kerberosAuthenticationFailureHandler);
              return filter;
          }
          
          @Bean
          public SimpleUrlAuthenticationFailureHandler kerberosAuthenticationFailureHandler() {
              SimpleUrlAuthenticationFailureHandler handler = new SimpleUrlAuthenticationFailureHandler(&quot;/oauth2/authorization/login&quot;);
              handler.setUseForward(true);
              return handler;
          }
  
  
          @Bean
          public SpnegoEntryPoint spnegoEntryPoint() {
              return new SpnegoEntryPoint(&quot;/oauth2/authorization/login&quot;);
          }
  
  // SecurityConfig
          @Bean
          public SecurityFilterChain filterChain(final HttpSecurity http,
                                                 LdapLogoutSuccessHandler ldapLogoutSuccessHandler,
                                                 CompositeFilter customFilter,
                                                 SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter) throws Exception {
              return http.antMatcher(&quot;/**&quot;)
                  .exceptionHandling()
                  .authenticationEntryPoint(spnegoEntryPoint())
                  .accessDeniedHandler(new RedirectingAccessDeniedHandler(env.getProperty(&quot;http.403.redirectUrl&quot;)))
                      .and()
                  .authorizeRequests()
                  .antMatchers(&quot;/accessDenied&quot;, &quot;/accessDenied.do&quot;, &quot;/admin/userGroup/rest/fullSync&quot;, &quot;/login**&quot;)
                  .permitAll()
                  .anyRequest().authenticated()
                  .and()
                  .formLogin()
                  .loginPage(&quot;/oauth2/authorization/login&quot;)
                  .loginProcessingUrl(&quot;/oauth2/authorization/springLogin&quot;)
                  .failureUrl(&quot;/oauth2/authorization/login?error=1&quot;)
                  .permitAll()
                  .and()
                  .addFilterBefore(spnegoAuthenticationProcessingFilter, BasicAuthenticationFilter.class).build();
          }
  
  // Authorization Server
          @Bean
          public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
              OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
              return http.formLogin(Customizer.withDefaults()).build();
          }
  
  // Resource Server
          @Bean
          public SecurityFilterChain resourceServerSecurityFilterChain(HttpSecurity http, CompositeFilter customFilter) throws Exception {
              http.antMatcher(&quot;/oauth2/resource/**&quot;)
                  .authorizeRequests()
                  .anyRequest().authenticated()
                  .and()
                  .oauth2ResourceServer().jwt(jwt -&gt; jwt.jwtAuthenticationConverter(authenticationConverter));
              
              return http.build();
          }
  </code></pre>
  <p>My current error is</p>
  <pre><code>2022-09-21 09:40:52,445 ERROR org.springframework.boot.web.servlet.support.ErrorPageFilter - Forwarding to error page from request [/actuator/health] due to exception [javax.security.auth.login.LoginException: Client not found in Kerberos database (6)]
  java.lang.RuntimeException: javax.security.auth.login.LoginException: Client not found in Kerberos database (6)
      at com.kerb4j.common.jaas.sun.Krb5LoginContext.loginWithUsernameAndPassword(Krb5LoginContext.java:53) ~[kerb4j-common-0.1.2.jar:?]
      at com.kerb4j.client.SpnegoClient$2.call(SpnegoClient.java:157) ~[kerb4j-common-0.1.2.jar:?]
      at com.kerb4j.client.SpnegoClient$2.call(SpnegoClient.java:154) ~[kerb4j-common-0.1.2.jar:?]
      at com.kerb4j.client.SpnegoClient$1.call(SpnegoClient.java:93) ~[kerb4j-common-0.1.2.jar:?]
      at com.kerb4j.client.SpnegoClient$1.call(SpnegoClient.java:89) ~[kerb4j-common-0.1.2.jar:?]
      at com.kerb4j.client.SpnegoClient.getSubject(SpnegoClient.java:219) ~[kerb4j-common-0.1.2.jar:?]
      at com.kerb4j.server.spring.KerberosAuthenticationProvider.authenticate(KerberosAuthenticationProvider.java:43) ~[kerb4j-server-spring-security-0.1.2.jar:?]
      at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.7.3.jar:5.7.3]
      at com.kerb4j.server.spring.SpnegoAuthenticationProcessingFilter.doFilterInternal(SpnegoAuthenticationProcessingFilter.java:165) ~[kerb4j-server-spring-security-0.1.2.jar:?]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:223) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:112) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:82) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) ~[spring-security-web-5.7.3.jar:5.7.3]
      at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.22.jar:5.3.22]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.62]
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.62]
      at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.62]
      at org.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter.doFilter(TracingFilter.java:89) ~[spring-cloud-sleuth-instrumentation-3.1.1.jar:3.1.1]
      at org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebServletConfiguration$LazyTracingFilter.doFilter(TraceWebServletConfiguration.java:131) ~[spring-cloud-sleuth-autoconfigure-3.1.1.jar:3.1.1]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.62]
      at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) ~[spring-boot-actuator-2.7.3.jar:2.7.3]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.62]
      at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126) ~[spring-boot-2.7.3.jar:2.7.3]
      at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64) ~[spring-boot-2.7.3.jar:2.7.3]
      at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101) ~[spring-boot-2.7.3.jar:2.7.3]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119) ~[spring-boot-2.7.3.jar:2.7.3]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.62]
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.22.jar:5.3.22]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.62]
      at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71) ~[log4j-web-2.17.2.jar:2.17.2]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[catalina.jar:9.0.62]
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[catalina.jar:9.0.62]
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[catalina.jar:9.0.62]
      at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) ~[catalina.jar:9.0.62]
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[catalina.jar:9.0.62]
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[catalina.jar:9.0.62]
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-coyote.jar:9.0.62]
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-coyote.jar:9.0.62]
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-coyote.jar:9.0.62]
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-coyote.jar:9.0.62]
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-coyote.jar:9.0.62]
      at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-util.jar:9.0.62]
      at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-util.jar:9.0.62]
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-util.jar:9.0.62]
      at java.lang.Thread.run(Thread.java:834) ~[?:?]
  Caused by: javax.security.auth.login.LoginException: Client not found in Kerberos database (6)
      at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:782) ~[jdk.security.auth:?]
      at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:592) ~[jdk.security.auth:?]
      at javax.security.auth.login.LoginContext.invoke(LoginContext.java:726) ~[?:?]
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:665) ~[?:?]
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:663) ~[?:?]
      at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
      at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:663) ~[?:?]
      at javax.security.auth.login.LoginContext.login(LoginContext.java:574) ~[?:?]
      at com.kerb4j.common.jaas.sun.Krb5LoginContext.loginWithUsernameAndPassword(Krb5LoginContext.java:50) ~[kerb4j-common-0.1.2.jar:?]
      ... 85 more
  Caused by: sun.security.krb5.KrbException: Client not found in Kerberos database (6)
      at sun.security.krb5.KrbAsRep.&lt;init&gt;(KrbAsRep.java:76) ~[java.security.jgss:?]
      at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:345) ~[java.security.jgss:?]
      at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:498) ~[java.security.jgss:?]
      at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:744) ~[jdk.security.auth:?]
      at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:592) ~[jdk.security.auth:?]
      at javax.security.auth.login.LoginContext.invoke(LoginContext.java:726) ~[?:?]
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:665) ~[?:?]
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:663) ~[?:?]
      at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
      at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:663) ~[?:?]
      at javax.security.auth.login.LoginContext.login(LoginContext.java:574) ~[?:?]
      at com.kerb4j.common.jaas.sun.Krb5LoginContext.loginWithUsernameAndPassword(Krb5LoginContext.java:50) ~[kerb4j-common-0.1.2.jar:?]
      ... 85 more
  Caused by: sun.security.krb5.Asn1Exception: Identifier doesn't match expected value (906)
      at sun.security.krb5.internal.KDCRep.init(KDCRep.java:140) ~[java.security.jgss:?]
      at sun.security.krb5.internal.ASRep.init(ASRep.java:64) ~[java.security.jgss:?]
      at sun.security.krb5.internal.ASRep.&lt;init&gt;(ASRep.java:59) ~[java.security.jgss:?]
      at sun.security.krb5.KrbAsRep.&lt;init&gt;(KrbAsRep.java:60) ~[java.security.jgss:?]
      at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:345) ~[java.security.jgss:?]
      at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:498) ~[java.security.jgss:?]
      at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:744) ~[jdk.security.auth:?]
      at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:592) ~[jdk.security.auth:?]
      at javax.security.auth.login.LoginContext.invoke(LoginContext.java:726) ~[?:?]
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:665) ~[?:?]
      at javax.security.auth.login.LoginContext$4.run(LoginContext.java:663) ~[?:?]
      at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
      at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:663) ~[?:?]
      at javax.security.auth.login.LoginContext.login(LoginContext.java:574) ~[?:?]
      at com.kerb4j.common.jaas.sun.Krb5LoginContext.loginWithUsernameAndPassword(Krb5LoginContext.java:50) ~[kerb4j-common-0.1.2.jar:?]
      ... 85 more
  </code></pre>