Spring 安全中的自定义身份验证控制器
Custom authentication controller in Spring Security
使用 Spring 安全性时,是否可以添加自定义控制器以在使用 loginProcessingUrl
时执行 POST
?据我所知,这与 UsernamePasswordAuthenticationFilter
.
有关
我当前的安全配置是这样的,
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.csrf()
.disable()
.addFilterBefore(statelessCsrfFilter(), CsrfFilter.class);
http
.addFilterAfter(requestInterceptorFilter(), CsrfFilter.class)
.authorizeRequests()
.antMatchers(
"/resources/**",
"/css/**",
"/img/**",
"/js/**",
"/webjars/**",
"/management/**",
"/api/v1/auth/login",
"/api/v1/auth/logout",
"/api/v1/auth/token",
"/api/v1/auth/forgot-password",
"/api/v1/auth/management/**"
).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/api/v1/auth/login")
.loginProcessingUrl("/api/v1/auth/login")
.permitAll()
.failureHandler(failureHandler());
// @formatter:on
}
所有这一切的原因是因为当我使用 micrometer
提取指标时,我看到以下异常,
2018-11-15 20:36:42.449 DEBUG [auth-service,,,] 43751 --- [ XNIO-2 task-14] i.m.s.web.servlet.WebMvcMetricsFilter : Unable to time request
org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:205)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:374)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:314)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:61)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:352)
at org.springframework.web.servlet.handler.HandlerMappingIntrospector.getMatchableHandlerMapping(HandlerMappingIntrospector.java:123)
at io.micrometer.spring.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletChain.handleRequest(ServletChain.java:65)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access0(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access[=12=]0(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:336)
at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:830)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
此时我的猜测是 Micrometer 的 WebMvcMetricsFilter
绑定到 Spring MVC 过滤器链并且它不知道 Spring 安全过滤器链。我将此作为一个问题 #1011 提出,但想知道我是否可以通过为 POST
.
声明我自己的控制器来解决这个问题
我围绕这个问题的 PoC -> spring-boot-spring-security-micrometer
感谢任何关于此的建议。
如上面的评论所述,此问题实际上源于 Spring 安全性(在 Spring Boot 1.5.x 上测试,如 PoC spring-boot-spring-security-micrometer 中给出)。
因此,这将通过千分尺问题解决 #15204。
使用 Spring 安全性时,是否可以添加自定义控制器以在使用 loginProcessingUrl
时执行 POST
?据我所知,这与 UsernamePasswordAuthenticationFilter
.
我当前的安全配置是这样的,
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.csrf()
.disable()
.addFilterBefore(statelessCsrfFilter(), CsrfFilter.class);
http
.addFilterAfter(requestInterceptorFilter(), CsrfFilter.class)
.authorizeRequests()
.antMatchers(
"/resources/**",
"/css/**",
"/img/**",
"/js/**",
"/webjars/**",
"/management/**",
"/api/v1/auth/login",
"/api/v1/auth/logout",
"/api/v1/auth/token",
"/api/v1/auth/forgot-password",
"/api/v1/auth/management/**"
).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/api/v1/auth/login")
.loginProcessingUrl("/api/v1/auth/login")
.permitAll()
.failureHandler(failureHandler());
// @formatter:on
}
所有这一切的原因是因为当我使用 micrometer
提取指标时,我看到以下异常,
2018-11-15 20:36:42.449 DEBUG [auth-service,,,] 43751 --- [ XNIO-2 task-14] i.m.s.web.servlet.WebMvcMetricsFilter : Unable to time request
org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:205)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:374)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:314)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:61)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:352)
at org.springframework.web.servlet.handler.HandlerMappingIntrospector.getMatchableHandlerMapping(HandlerMappingIntrospector.java:123)
at io.micrometer.spring.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletChain.handleRequest(ServletChain.java:65)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access0(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access[=12=]0(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:336)
at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:830)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
此时我的猜测是 Micrometer 的 WebMvcMetricsFilter
绑定到 Spring MVC 过滤器链并且它不知道 Spring 安全过滤器链。我将此作为一个问题 #1011 提出,但想知道我是否可以通过为 POST
.
我围绕这个问题的 PoC -> spring-boot-spring-security-micrometer
感谢任何关于此的建议。
如上面的评论所述,此问题实际上源于 Spring 安全性(在 Spring Boot 1.5.x 上测试,如 PoC spring-boot-spring-security-micrometer 中给出)。
因此,这将通过千分尺问题解决 #15204。