Estoy usando Spring MVC @ControllerAdvice
y @ExceptionHandler
para manejar toda la excepción de una API REST. Funciona bien para las excepciones lanzadas por los controladores web mvc, pero no funciona para las excepciones lanzadas por los filtros personalizados de seguridad de primavera porque se ejecutan antes de que se invoquen los métodos del controlador.
Tengo un filtro de seguridad de primavera personalizado que realiza una autenticación basada en 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);
}
}
}
Con este punto 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());
}
}
Y con esta clase para manejar excepciones a nivel mundial:
@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;
}
}
Lo que tengo que hacer es devolver un cuerpo JSON detallado incluso para Spring Security AuthenticationException. ¿Hay alguna manera de hacer que Spring Security AuthenticationEntryPoint y spring mvc @ExceptionHandler funcionen juntos?
Estoy usando Spring Security 3.1.4 y Spring MVC 3.2.4.
(@)ExceptionHandler
solo funcionará si la solicitud es manejada porDispatcherServlet
. Sin embargo, esta excepción ocurre antes de eso, ya que es lanzada por unFilter
. Por lo tanto, nunca podrá manejar esta excepción con un(@)ExceptionHandler
.