私は春のMVCのを使用しています@ControllerAdvice
し、@ExceptionHandler
REST APIをすべての例外を処理します。これは、Web MVCコントローラーによってスローされた例外に対しては正常に機能しますが、コントローラーメソッドが呼び出される前に実行されるため、Spring Securityカスタムフィルターによってスローされた例外に対しては機能しません。
トークンベースの認証を行うカスタムSpring Securityフィルターがあります。
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;
}
}
Spring Security AuthenticationExceptionの場合でも、詳細なJSON本文を返す必要があります。Spring Security AuthenticationEntryPointとSpring MVC @ExceptionHandlerを連携させる方法はありますか?
Spring Security 3.1.4とSpring MVC 3.2.4を使用しています。
(@)ExceptionHandler
は、リクエストがによって処理された場合にのみ機能しDispatcherServlet
ます。ただし、この例外はによってスローされるため、その前に発生しFilter
ます。したがって、この例外をで処理することはできません(@)ExceptionHandler
。