Spring Security Win Auth 示例未正确验证 - 在明确传入并确认时显示空密钥表文件

Spring Security Win Auth example is not authenticating properly - says null keytab file when it is clearly being passed in and acknowledged

我已经下载并尝试测试 sec-server-win-auth 示例应用程序 Spring 安全扩展。我执行了以下步骤:

  1. 下载并构建 spring-security-Kerberos-master 项目。
  2. 把sec-server-win-auth-1.0.0.BUILD-SNAPSHOT.jar 拉出来放到一个 PROD 服务器上的文件夹。
  3. 在与我的自定义相同的文件夹中创建一个新的 application.yml 资讯
  4. 在我的测试域控制器上创建一个名为 DC 的 tomcat.keytab。
  5. 将 tomcat.keytab 文件复制到我的 PROD 服务器。
  6. 运行 java -jar sec-server-win-auth-1.0.0.BUILD-SNAPSHOT.jar
  7. 在单独的客户端 CLIENT1 上,打开 IE 并转到 http://PROD:8080/

此时,我看到 Kerberos 协商 header 的请求和 header 的响应。它说它是有效的并尝试对其进行身份验证,但我收到以下错误。 "unable to obtain password from user"

此错误来自 Krb5LoginModule。此错误上方的问题提示说主体的密钥在 keytab 文件中不可用。主体可用,它只是为我的 keytab 文件获取空值。

Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is null     refreshKrb5Config is false principal is HTTP/DC.domain.local@DOMAI
N.LOCAL tryFirstPass is false useFirstPass is false storePass is false  clearPass is false
Key for the principal HTTP/DC.domain.local@DOMAIN.LOCAL not available in default key tab
                [Krb5LoginModule] authentication failed
Unable to obtain password from user

如果我进一步查看日志流,我可以看到 keytab 文件正在从 application.yml 正确传递并正在加载。

useKeyTab=true, keyTab=c:/kerberos/tomcat.keytab, debug=true, doNotPrompt=true}
Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is c:/kerberos/tomcat.keytab refreshKrb5Config is false principal is HTTP
/DC.domain.local@DOMAIN.LOCAL tryFirstPass is false useFirstPass is false storePass is false clearPass is false
principal is HTTP/DC.domain.local@DOMAIN.LOCAL
Will use keytab
Commit Succeeded

我不确定为什么我的 keytab 会在后面显示为 null。任何人都可以阐明这一点吗?

INFO 4564 --- [           main] demo.app.Application                     : Starting Application v1.0.0.BUILD-SNAPSHOT on PROD with PID 4564 (C:\kerberos\sec-server-win-auth-1.
0.0.BUILD-SNAPSHOT.jar started by tc01 in c:\kerberos)
INFO 4564 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@5
6459b78: startup date [Fri Mar 27 23 EDT 2015]; root of context hierarchy
INFO 4564 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scop
e=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$White
labelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/Error
MvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=
false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName
=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
INFO 4564 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [c
lass org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$c6bd8b6a] is not eligible for getting processed by all BeanPostProcessors (for example:
not eligible for auto-proxying)
INFO 4564 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'transactionAttributeSource' of type [class org.springframework.transaction.annotation.Annotati
onTransactionAttributeSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO 4564 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'transactionInterceptor' of type [class org.springframework.transaction.interceptor.Transaction
Interceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO 4564 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.config.internalTransactionAdvisor' of type [class org.springfr
amework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO 4564 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
INFO 4564 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
INFO 4564 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.15
INFO 4564 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
INFO 4564 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2543 ms
WARN 4564 --- [ost-startStop-1] o.s.s.e.k.SunJaasKerberosTicketValidator : Initial Keytab location is:file:/c:/kerberos/tomcat.keytab
WARN 4564 --- [ost-startStop-1] o.s.s.e.k.SunJaasKerberosTicketValidator : Your keytab starts with file:.  Stripping it from path for Java 7 compatibility. TP
WARN 4564 --- [ost-startStop-1] o.s.s.e.k.SunJaasKerberosTicketValidator : Loading Keytab file from the following path: c:/kerberos/tomcat.keytab
WARN 4564 --- [ost-startStop-1] o.s.s.e.k.SunJaasKerberosTicketValidator : loginConfig data is:{isInitiator=false, storeKey=true, principal=HTTP/DC.domain.local@DOMAIN.LOCAL,
useKeyTab=true, keyTab=c:/kerberos/tomcat.keytab, debug=true, doNotPrompt=true}
Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is c:/kerberos/tomcat.keytab refreshKrb5Config is false principal is HTTP
/DC.domain.local@DOMAIN.LOCAL tryFirstPass is false useFirstPass is false storePass is false clearPass is false
principal is HTTP/DC.domain.local@DOMAIN.LOCAL
Will use keytab
Commit Succeeded

INFO 4564 --- [ost-startStop-1] o.s.s.e.k.c.KerberosLdapContextSource    :  URL 'ldap://DC.DOMAIN.LOCAL/', root DN is ''
DEBUG 4564 --- [ost-startStop-1] o.s.l.c.support.AbstractContextSource    : AuthenticationSource not set - using default implementation
INFO 4564 --- [ost-startStop-1] o.s.l.c.support.AbstractContextSource    : Property 'userDn' not set - anonymous context will be used for read-write operations
DEBUG 4564 --- [ost-startStop-1] o.s.l.c.support.AbstractContextSource    : Using LDAP pooling.
DEBUG 4564 --- [ost-startStop-1] o.s.l.c.support.AbstractContextSource    : Trying provider Urls: ldap://DC.DOMAIN.LOCAL/
DEBUG 4564 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for org.springframework.security.config.annotation
.web.configurers.PermitAllSupport$ExactUrlRequestMatcher@4f38d17a
DEBUG 4564 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for org.springframework.security.config.annotation
.web.configurers.PermitAllSupport$ExactUrlRequestMatcher@1b40c938
DEBUG 4564 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for org.springframework.security.config.annotation
.web.configurers.PermitAllSupport$ExactUrlRequestMatcher@3a5a8982
DEBUG 4564 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/logout', POST]
DEBUG 4564 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for org.springframework.security.config.annotation
.web.configurers.PermitAllSupport$ExactUrlRequestMatcher@cbbe2cf
DEBUG 4564 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/']
DEBUG 4564 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'permitAll', for Ant [pattern='/home']
DEBUG 4564 --- [ost-startStop-1] edFilterInvocationSecurityMetadataSource : Adding web access control expression 'authenticated', for org.springframework.security.web.util.matc
her.AnyRequestMatcher@1
DEBUG 4564 --- [ost-startStop-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Validated configuration attributes
DEBUG 4564 --- [ost-startStop-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Validated configuration attributes
INFO 4564 --- [ost-startStop-1] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [org.sprin
gframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@5c5a072a, org.springframework.security.web.context.SecurityContextPersistenceFilter@71142e50, org.springframework.securit
y.web.header.HeaderWriterFilter@709820cd, org.springframework.security.web.csrf.CsrfFilter@17fdb097, org.springframework.security.web.authentication.logout.LogoutFilter@653c5652, org.springframework.s
ecurity.web.authentication.UsernamePasswordAuthenticationFilter@6a5b07f2, org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter@1a8c85c4, org.springframework.securi
ty.web.savedrequest.RequestCacheAwareFilter@4c3d80e9, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@11e86f65, org.springframework.security.web.authentication.Anon
ymousAuthenticationFilter@7fa21479, org.springframework.security.web.session.SessionManagementFilter@40d2c946, org.springframework.security.web.access.ExceptionTranslationFilter@72b368f3, org.springfr
amework.security.web.access.intercept.FilterSecurityInterceptor@1ed5eb39]
INFO 4564 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
INFO 4564 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'characterEncodingFilter' to: [/*]
INFO 4564 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'springSecurityFilterChain' to: [/*]
INFO 4564 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'spnegoAuthenticationProcessingFilter' to: [/*]
INFO 4564 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
DEBUG 4564 --- [ost-startStop-1] k.w.SpnegoAuthenticationProcessingFilter : Initializing filter 'spnegoAuthenticationProcessingFilter'
DEBUG 4564 --- [ost-startStop-1] k.w.SpnegoAuthenticationProcessingFilter : Filter 'spnegoAuthenticationProcessingFilter' configured successfully
DEBUG 4564 --- [ost-startStop-1] o.s.security.web.FilterChainProxy        : Initializing filter 'springSecurityFilterChain'
DEBUG 4564 --- [ost-startStop-1] o.s.security.web.FilterChainProxy        : Filter 'springSecurityFilterChain' configured successfully
INFO 4564 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWeb
ApplicationContext@56459b78: startup date [Fri Mar 27 23 EDT 2015]; root of context hierarchy
INFO 4564 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public or
g.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
INFO 4564 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto
public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
INFO 4564 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/hello] onto handler of type [class org.springframework.web.servlet.mvc.Parameteriz
ableViewController]
INFO 4564 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/home] onto handler of type [class org.springframework.web.servlet.mvc.Parameteriza
bleViewController]
INFO 4564 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/login] onto handler of type [class org.springframework.web.servlet.mvc.Parameteriz
ableViewController]
INFO 4564 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Root mapping to handler of type [class org.springframework.web.servlet.mvc.ParameterizableViewContro
ller]
INFO 4564 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceH
ttpRequestHandler]
INFO 4564 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.R
esourceHttpRequestHandler]
INFO 4564 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resour
ce.ResourceHttpRequestHandler]
INFO 4564 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
INFO 4564 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
INFO 4564 --- [           main] demo.app.Application                     : Started Application in 5.523 seconds (JVM running for 6.365)
INFO 4564 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
INFO 4564 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
INFO 4564 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 32 ms
DEBUG 4564 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /hello at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFil
ter'
DEBUG 4564 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /hello at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFil
ter'
DEBUG 4564 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
DEBUG 4564 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
DEBUG 4564 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /hello at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
DEBUG 4564 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web
.header.writers.HstsHeaderWriter$SecureRequestMatcher@33baf8cf
DEBUG 4564 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /hello at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
DEBUG 4564 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /hello at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG 4564 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /hello' doesn't match 'POST /logout
DEBUG 4564 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /hello at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticatio
nFilter'
DEBUG 4564 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /hello' doesn't match 'POST /login
DEBUG 4564 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /hello at position 7 of 13 in additional filter chain; firing Filter: 'SpnegoAuthenticationProcessin
gFilter'
DEBUG 4564 --- [nio-8080-exec-1] k.w.SpnegoAuthenticationProcessingFilter : Received Negotiate Header for request http://prod:8080/hello: Negotiate YIIGPwYGKwYBBQUCoIIGMzCCBi+g
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
DEBUG 4564 --- [nio-8080-exec-1] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.extensions.kerberos.KerberosServiceAuthent
icationProvider
DEBUG 4564 --- [nio-8080-exec-1] .k.KerberosServiceAuthenticationProvider : Try to validate Kerberos Token
DEBUG 4564 --- [nio-8080-exec-1] .k.KerberosServiceAuthenticationProvider : Succesfully validated spectrum@DOMAIN.LOCAL
DEBUG 4564 --- [nio-8080-exec-1] o.s.s.l.s.FilterBasedLdapUserSearch      : Searching for user 'spectrum@DOMAIN.LOCAL', with user search [ searchFilter: '(| (userPrincipalName=
{0}) (sAMAccountName={0}))', searchBase: 'CN=Users,DC=domain,DC=local', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is HTTP/DC.domain.local@DOMAI
N.LOCAL tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Key for the principal HTTP/DC.domain.local@DOMAIN.LOCAL not available in default key tab
                [Krb5LoginModule] authentication failed
Unable to obtain password from user

DEBUG 4564 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG 4564 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
ERROR 4564 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

org.springframework.ldap.AuthenticationException: Unable to obtain password from user
; nested exception is javax.naming.AuthenticationException: Unable to obtain password from user
 [Root exception is javax.security.auth.login.LoginException: Unable to obtain password from user
]
        at org.springframework.ldap.support.LdapUtils.convertLdapException(LdapUtils.java:182)
        at org.springframework.ldap.core.support.AbstractContextSource.createContext(AbstractContextSource.java:285)
        at org.springframework.ldap.core.support.AbstractContextSource.doGetContext(AbstractContextSource.java:119)
        at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:138)
        at org.springframework.ldap.core.LdapTemplate.executeReadOnly(LdapTemplate.java:791)
        at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntry(SpringSecurityLdapTemplate.java:194)
        at org.springframework.security.ldap.search.FilterBasedLdapUserSearch.searchForUser(FilterBasedLdapUserSearch.java:116)
        at org.springframework.security.ldap.userdetails.LdapUserDetailsService.loadUserByUsername(LdapUserDetailsService.java:38)
        at org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider.authenticate(KerberosServiceAuthenticationProvider.java:69)
        at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
        at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)
        at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
        at org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter.doFilter(SpnegoAuthenticationProcessingFilter.java:145)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
<1 - snipped ->
        at java.lang.Thread.run(Unknown Source)
Caused by: javax.naming.AuthenticationException: Unable to obtain password from user

        at org.springframework.security.extensions.kerberos.client.KerberosLdapContextSource.login(KerberosLdapContextSource.java:143)
        at org.springframework.security.extensions.kerberos.client.KerberosLdapContextSource.getDirContextInstance(KerberosLdapContextSource.java:102)
        at org.springframework.ldap.core.support.AbstractContextSource.createContext(AbstractContextSource.java:273)
        ... 51 common frames omitted
Caused by: javax.security.auth.login.LoginException: Unable to obtain password from user

        at com.sun.security.auth.module.Krb5LoginModule.promptForPass(Unknown Source)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Unknown Source)
        at com.sun.security.auth.module.Krb5LoginModule.login(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at javax.security.auth.login.LoginContext.invoke(Unknown Source)
        at javax.security.auth.login.LoginContext.access[=13=]0(Unknown Source)
        at javax.security.auth.login.LoginContext.run(Unknown Source)
        at javax.security.auth.login.LoginContext.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
        at javax.security.auth.login.LoginContext.login(Unknown Source)
        at org.springframework.security.extensions.kerberos.client.KerberosLdapContextSource.login(KerberosLdapContextSource.java:139)
        ... 53 common frames omitted

我明白这里出了什么问题,这是我的错误。WebSecurityConfig 中的SunJaasKrb5LoginConfig 未创建为 bean,因此未调用 afterPropertiesSet(),从而导致您刚刚报告的内容。

  1. WebSecurityConfig.kerberosLdapContextSource()中手动调用loginConfig.afterPropertiesSet()

  2. 或者以正常的 spring 方式创建 SunJaasKrb5LoginConfig 作为 bean 并让框架调用它的 afterPropertiesSet().

由于复杂的 krb 设置,我不得不在测试中使用 -Djava.security.krb5.conf=/path/to/krb5.ini,并且我在那里有密钥表文件的路径。

我修复了 https://github.com/spring-projects/spring-security-kerberos/commit/f354bc29f2c6558456cfc7fbfc84d0c1b6fd0606,如果这解决了您的问题,请告诉我们。