J'utilise Spring MVC @ControllerAdvice
et @ExceptionHandler
pour gérer toutes les exceptions d'une API REST. Cela fonctionne bien pour les exceptions levées par les contrôleurs Web mvc, mais cela ne fonctionne pas pour les exceptions levées par les filtres personnalisés de sécurité Spring, car ils s'exécutent avant que les méthodes du contrôleur ne soient appelées.
J'ai un filtre de sécurité Spring personnalisé qui effectue une authentification basée sur des jetons:
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);
}
}
}
Avec ce point d'entrée personnalisé:
@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());
}
}
Et avec cette classe pour gérer les exceptions globalement:
@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;
}
}
Ce que je dois faire est de renvoyer un corps JSON détaillé, même pour Spring Security AuthenticationException. Existe-t-il un moyen de faire en sorte que Spring Security AuthenticationEntryPoint et spring mvc @ExceptionHandler fonctionnent ensemble?
J'utilise Spring Security 3.1.4 et Spring mvc 3.2.4.
(@)ExceptionHandler
ne fonctionnera que si la demande est gérée par leDispatcherServlet
. Cependant, cette exception se produit avant cela car elle est levée par unFilter
. Vous ne pourrez donc jamais gérer cette exception avec un fichier(@)ExceptionHandler
.