Я использую Spring MVC @ControllerAdvice
и @ExceptionHandler
обрабатываю все исключения REST Api. Он отлично работает для исключений, создаваемых веб-контроллерами mvc, но не работает для исключений, создаваемых настраиваемыми фильтрами безопасности Spring, поскольку они запускаются до вызова методов контроллера.
У меня есть настраиваемый фильтр безопасности Spring, который выполняет аутентификацию на основе токенов:
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);
}
}
}
С помощью этой настраиваемой точки входа:
@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());
}
}
И с этим классом для глобальной обработки исключений:
@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;
}
}
Что мне нужно сделать, так это вернуть подробное тело JSON даже для Spring Security AuthenticationException. Есть ли способ заставить Spring Security AuthenticationEntryPoint и spring mvc @ExceptionHandler работать вместе?
Я использую Spring Security 3.1.4 и Spring MVC 3.2.4.
(@)ExceptionHandler
Будет работать, только если запрос обрабатываетсяDispatcherServlet
. Однако это исключение возникает раньше, поскольку оно вызывается объектомFilter
. Таким образом, вы никогда не сможете обработать это исключение с помощью(@)ExceptionHandler
.