Lidar com exceções de autenticação de segurança de primavera com @ExceptionHandler
Estou usando o Spring MVC@ControllerAdvice
e@ExceptionHandler
para manipular todas as exceções de uma API REST. Ele funciona bem para exceções lançadas por controladores mvc da web, mas não funciona para exceções lançadas por filtros personalizados de segurança de mola porque elas são executadas antes dos métodos do controlador serem chamados.
Eu tenho um filtro de segurança de mola personalizado que faz uma autenticação baseada em token:
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);
}
}
}
Com este ponto de entrada personalizado:
@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());
}
}
E com essa classe para lidar com exceções globalmente:
@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;
}
}
O que eu preciso fazer é retornar um corpo JSON detalhado mesmo para a autenticação de segurança AuthenticationException. Existe uma maneira de fazer com que a segurança de primavera AuthenticationEntryPoint e o Spring mvc @ExceptionHandler funcionem juntos?
Estou usando o spring security 3.1.4 e o spring mvc 3.2.4.