@kopelitsaの回答に基づいたソリューションを提供したかったのです。主な違いは次のとおりです。
- を使用してコントローラの例外処理を再利用する
HandlerExceptionResolver
。
- XML構成でのJava構成の使用
まず、通常のRestController / Controllerで発生する例外を処理するクラス(@RestControllerAdvice
または@ControllerAdvice
で注釈が付けられたクラス、およびで注釈が付けられたメソッド)があることを確認する必要があります@ExceptionHandler
。これは、コントローラーで発生する例外を処理します。RestControllerAdviceの使用例を次に示します。
@RestControllerAdvice
public class ExceptionTranslator {
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorDTO processRuntimeException(RuntimeException e) {
return createErrorDTO(HttpStatus.INTERNAL_SERVER_ERROR, "An internal server error occurred.", e);
}
private ErrorDTO createErrorDTO(HttpStatus status, String message, Exception e) {
(...)
}
}
この動作をSpring Securityフィルターチェーンで再利用するには、フィルターを定義して、セキュリティ構成にフックする必要があります。フィルターは、例外を上記で定義された例外処理にリダイレクトする必要があります。次に例を示します。
@Component
public class FilterChainExceptionHandler extends OncePerRequestFilter {
private final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (Exception e) {
log.error("Spring Security Filter Chain Exception:", e);
resolver.resolveException(request, response, null, e);
}
}
}
次に、作成したフィルターをSecurityConfigurationに追加する必要があります。先行するすべてのフィルターの例外はキャッチされないため、非常に早い段階でチェーンにフックする必要があります。私の場合、の前に追加するのが妥当でしたLogoutFilter
。公式ドキュメントでデフォルトのフィルターチェーンとその順序を確認してください。次に例を示します。
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private FilterChainExceptionHandler filterChainExceptionHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(filterChainExceptionHandler, LogoutFilter.class)
(...)
}
}