Estou usando Spring MVC @ControllerAdvice
e @ExceptionHandler
para lidar com todas as exceções de um REST Api. Ele funciona bem para exceções lançadas por controladores web mvc, mas não funciona para exceções lançadas por filtros personalizados de segurança Spring porque eles são executados antes de os 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 esta 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 Spring security AuthenticationException. Existe uma maneira de fazer o spring security AuthenticationEntryPoint e spring mvc @ExceptionHandler trabalharem juntos?
Estou usando o spring security 3.1.4 e o spring mvc 3.2.4.
(@)ExceptionHandler
só funcionará se a solicitação for tratada peloDispatcherServlet
. No entanto, essa exceção ocorre antes disso, pois é lançada por aFilter
. Portanto, você nunca será capaz de lidar com essa exceção com um(@)ExceptionHandler
.