Я использую Spring Security Web 5.0.9 и Tomcat 8. ExceptionTranslationFilter throw ServletException "Невозможно обработать Spring Security Exception, потому что ответ уже зафиксирован."Я копаюсь в исходном коде и нахожу причину.Я не уверен, является ли это ошибкой для безопасности весны.
Я выбрасываю исключение UsernameNotFoundException в AuthenticationUserDetailsService.loadUserDetails
SimpleUrlAuthenticationFailureHandler.onAuthenticationFailure catchисключение, а затем вызовите
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
if (defaultFailureUrl == null) {
logger.debug("No failure URL set, sending 401 Unauthorized error");
response.sendError(HttpStatus.UNAUTHORIZED.value(),
HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
sendError установит ответ, зафиксированный в true, см. ResponseFacade.java:
public void sendError(int sc, String msg)
throws IOException {
...
response.setAppCommitted(true);
...
}
Затем ExceptionTranslationFilter перехватывает его и проверяет состояние фиксации ответа, находит его истинным, а затем выдает исключение
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
...
if (response.isCommitted()) {
throw new ServletException("Unable to handle the Spring Security Exception because the response is already committed.", ex);
...
}
никто не ловит ServletException, и приложение пытается найти /web_framework/error_page/405.html
Я считаю, что код безопасности пружины изменен в этом исправлении ошибки https://github.com/spring-projects/spring-security/issues/5273.
Как работать с ServletException и возвращать действительный ответ 401, но не web_framework / error_page / 405.html