I have a Spring Boot app using Jersey as the JAX-RS implementation. This is my security configuration:
@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();
}
}
What I want to be able to do is to have a way to catch the Exceptions thrown by my TokenAuthenticationProvider and convert them into a standardized JSON format that we have agreed upon. Is there a way to do this? I tried messing around with adding a custom AuthenticationFailureHandler, but couldn't get that to work.
WebSecurityConfigurerAdapter appraoch
The
HttpSecurity
class has a method called exceptionHandling which can be used to override the default behavior. The following sample presents how the response message can be customized.@ControllerAdvice appraoch - Why it doesn't work in this case
At first I thought about
@ControllerAdvice
that catches authentication exceptions for the entire application.In the example above, the JSON is built manually, but you can simply return a POJO which will be mapped into JSON just like from a regular REST controller. Since Spring 4.3 you can also use @RestControllerAdvice, which is a combination of
@ControllerAdvice
and@ResponseBody
.However, this approach doesn't work because the exception is thrown by the
AbstractSecurityInterceptor
and handled by ExceptionTranslationFilter before any controller is reached.