我有一个使用Jersey作为JAX-RS实现的Spring Boot应用程序。这是我的安全配置:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired TokenAuthenticationProvider tokenAuthenticationProvider;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(tokenAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new AuthenticationTokenFilter(), BasicAuthenticationFilter.class)
.csrf().disable()
.authorizeRequests()
.antMatchers("/dataHub/**")
.authenticated();
}
}
我想要做的是有一种方法来捕获我的TokenAuthenticationProvider抛出的异常,并将它们转换为我们已经同意的标准化JSON格式。有没有办法做到这一点?我试着添加一个自定义的AuthenticationFailureHandler,但是无法让它工作。
答案 0 :(得分:12)
WebSecurityConfigurerAdapter appraoch
HttpSecurity
类有一个名为exceptionHandling的方法,可用于覆盖默认行为。以下示例介绍了如何自定义响应消息。
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// your custom configuration goes here
.exceptionHandling()
.authenticationEntryPoint((request, response, e) -> {
String json = String.format("{\"message\": \"%s\"}", e.getMessage());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
});
}
@ControllerAdvice appraoch - 为什么在这种情况下不起作用
首先,我想到@ControllerAdvice
可以捕获整个应用程序的身份验证异常。
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
@ControllerAdvice
public class AuthExceptionHandler {
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(AuthenticationException.class)
@ResponseBody
public String handleAuthenticationException(AuthenticationException e) {
return String.format("{\"message\": \"%s\"}", e.getMessage());
}
}
在上面的示例中,JSON是手动构建的,但您可以简单地返回一个POJO,它将映射到JSON,就像从常规REST控制器一样。从Spring 4.3开始,您还可以使用@RestControllerAdvice,@ControllerAdvice
和@ResponseBody
的组合。
但是,此方法不起作用,因为AbstractSecurityInterceptor
抛出异常并在到达任何控制器之前由ExceptionTranslationFilter处理。