Dil*_*anD 6 security authentication spring credentials basic-authentication
我有一个使用基本身份验证运行spring security的spring boot应用程序.当提供适当的基本身份验证凭据时,一切都很好,但是对于不正确的身份验证凭据,spring会出现HttpRequestMethodNotSupportedException: Request method 'POST' not supported异常.
根据日志,Spring已经确定了身份验证失败,但这并不是出现的问题.
2015-08-12 09:33:10.922 INFO 16988 --- [nio-8080-exec-4] o.s.b.a.audit.listener.AuditListener : AuditEvent [timestamp=Wed Aug 12 09:33:10 AEST 2015, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]
2015-08-12 09:33:10.927 TRACE 16988 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Bound request context to thread: FirewalledRequest[ org.apache.catalina.core.ApplicationHttpRequest@483e1fc6]
2015-08-12 09:33:10.927 DEBUG 16988 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing POST request for [/myapplication/error]
2015-08-12 09:33:10.927 TRACE 16988 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Testing handler map [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping@331bb032] in DispatcherServlet with name 'dispatcherServlet'
2015-08-12 09:33:10.927 TRACE 16988 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : No handler mapping found for [/error]
2015-08-12 09:33:10.927 TRACE 16988 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Testing handler map [org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping@69e79b9b] in DispatcherServlet with name 'dispatcherServlet'
2015-08-12 09:33:10.927 TRACE 16988 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@27cc0354] in DispatcherServlet with name 'dispatcherServlet'
2015-08-12 09:33:10.927 DEBUG 16988 --- [nio-8080-exec-4] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2015-08-12 09:33:10.928 DEBUG 16988 --- [nio-8080-exec-4] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
使用上面的日志并在调试spring源之后,我发现在确定凭据不正确后,spring会创建BadCredentials异常,然后尝试重定向到"/ error",这个重定向导致了HttpMethodNotAllowed异常.(my应用程序没有/错误端点).
我尝试通过配置以下内容告诉spring不要使用/ error
`public class ServerCustomization扩展ServerProperties {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
super.customize(container);
container.addErrorPages(new ErrorPage(HttpStatus.UNAUTHORIZED, null));
}`
Run Code Online (Sandbox Code Playgroud)
这将使spring停止吐出HttpMethodnotallowed异常并使其产生401(未授权),但我的异常处理程序(使用配置@ControllerAdvice)未捕获此异常.
我也尝试过如下配置自定义身份验证入口点而没有任何运气.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
AlwaysSendUnauthorized401AuthenticationEntryPoint alwaysSendUnauthorized401AuthenticationEntryPoint =
new AlwaysSendUnauthorized401AuthenticationEntryPoint();
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().httpStrictTransportSecurity().xssProtection().and().authorizeRequests().anyRequest().fullyAuthenticated()
.and().csrf().disable();
http.exceptionHandling().authenticationEntryPoint(alwaysSendUnauthorized401AuthenticationEntryPoint);
}
public class AlwaysSendUnauthorized401AuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public final void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
Run Code Online (Sandbox Code Playgroud)
}
我们有什么方法可以指定spring不重定向到/ error并返回Bad Credentials Exception吗?
我创建了一个示例Spring Boot应用程序,其中包含以下安全配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("test").password("password").roles("USER");
}
@Bean
public AuthenticationEntryPoint authenticationEntryPoint() {
return (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().httpStrictTransportSecurity().xssProtection()
.and().authorizeRequests().anyRequest().fullyAuthenticated()
.and().csrf().disable();
http.httpBasic().authenticationEntryPoint(authenticationEntryPoint());
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint());
}
}
Run Code Online (Sandbox Code Playgroud)
输入无效的用户名/密码(除测试/密码以外的任何其他内容)时,我收到以下回复:
{"timestamp":1439381390204,"status":401,"error":"Unauthorized","message":"Bad credentials","path":"/"}
Run Code Online (Sandbox Code Playgroud)
这个错误是由org.springframework.boot.autoconfigure.web.BasicErrorController类返回的,如果你看一下,确实用@RequestMapping("/error")- errorHtml和error.定义了两个方法.既然你正在构建一个API,那么它应该是第二个被调用的,我会说这是"正确的"行为!
所以,首先,检查您是否BasicErrorController在验证失败时进入.如果你是,请确保你没有使用error方法errorHtml.
如果以上都不是有用的,请检查是否有人覆盖了错误控制器的默认行为.一个常见(和有效)扩展是实现自己的扩展org.springframework.boot.autoconfigure.web.ErrorAttributes以更改默认错误有效负载.但是BasicErrorController使用非标准实现替换整个过程同样容易,因此请在应用程序中检查它.
如果所有其他方法都失败了并且您坚持要禁用Spring的默认错误处理(我不建议这样做),请尝试将其添加到您的配置中:
@EnableAutoConfiguration(exclude = {ErrorMvcAutoConfiguration.class})
这样做的目的是确保错误控制器不会加载到应用程序上下文中.
| 归档时间: |
|
| 查看次数: |
10468 次 |
| 最近记录: |