1
votes

I'm using spring security web 5.0.9 and tomcat 8. ExceptionTranslationFilter throw ServletException "Unable to handle the Spring Security Exception because the response is already committed." I dig into the source code and find the root cause. I'm not sure whether it is a bug for spring security.

  1. I throw the UsernameNotFoundException in AuthenticationUserDetailsService.loadUserDetails

  2. SimpleUrlAuthenticationFailureHandler.onAuthenticationFailure catch the exception and then call

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());
        }

the sendError will set response committed to true, see ResponseFacade.java:

    public void sendError(int sc, String msg)
        throws IOException {
        ...
        response.setAppCommitted(true);
        ...

    }
  1. Then ExceptionTranslationFilter catch it and check the response commit status, found it's true and then throw the exception
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);
    ...
}
  1. nobody catch the ServletException and the application try to find the /web_framework/error_page/405.html

I find the spring security code is changed in this bug fix https://github.com/spring-projects/spring-security/issues/5273.

How to deal with the ServletException and return the valid 401 response, but not web_framework/error_page/405.html

1
Could you provide a Github sample - what is the simplest way to reproduce this issue? Generally, if the SimpleUrlAuthenticationFailureHandler is invoked, then the ExceptionTranslationFilter is not also invoked since there is no further response handling required.jzheaux
tks for you tips, I found that the old code add SimpleUrlAuthenticationFailureHandler manually, I remove it, and it works nowJay Fantasy
Hey, that's great! I've gone ahead and added that as an answer below so that it is easier to find for folks that run into the same kind of problem.jzheaux

1 Answers

0
votes

This sounds like it could be a misconfiguration in the code.

Typically, if the SimpleUrlAuthenticationFailureHandler is invoked, then the ExceptionTranslationFilter is not also invoked since there is no further response handling required.