I'm using Spring MVC's @ControllerAdvice
and @ExceptionHandler
to handle all the exception of a REST Api. It works fine for exceptions thrown by web mvc controllers but it does not work for exceptions thrown by spring security custom filters because they run before the controller methods are invoked.
I have a custom spring security filter that does a token based auth:
public class AegisAuthenticationFilter extends GenericFilterBean {
...
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
try {
...
} catch(AuthenticationException authenticationException) {
SecurityContextHolder.clearContext();
authenticationEntryPoint.commence(request, response, authenticationException);
}
}
}
With this custom entry point:
@Component("restAuthenticationEntryPoint")
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint{
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
}
}
And with this class to handle exceptions globally:
@ControllerAdvice
public class RestEntityResponseExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ InvalidTokenException.class, AuthenticationException.class })
@ResponseStatus(value = HttpStatus.UNAUTHORIZED)
@ResponseBody
public RestError handleAuthenticationException(Exception ex) {
int errorCode = AegisErrorCode.GenericAuthenticationError;
if(ex instanceof AegisException) {
errorCode = ((AegisException)ex).getCode();
}
RestError re = new RestError(
HttpStatus.UNAUTHORIZED,
errorCode,
"...",
ex.getMessage());
return re;
}
}
What I need to do is to return a detailed JSON body even for spring security AuthenticationException. Is there a way make spring security AuthenticationEntryPoint and spring mvc @ExceptionHandler work together?
I'm using spring security 3.1.4 and spring mvc 3.2.4.
(@)ExceptionHandler
will only work if the request is handled by theDispatcherServlet
. However this exception occurs before that as it is thrown by aFilter
. So you will never be able to handle this exception with an(@)ExceptionHandler
. – M. DeinumEntryPoint
. You might want to construct the object there, and inject aMappingJackson2HttpMessageConverter
in there. – M. Deinum