Search code examples
javaspring-boothttp-error

Why is Spring performing POST request to the registered error page?


My Spring Boot application serves POST requests at the login endpoint http://server.org/users/login, which may result in a 401 error. In this case, Spring is performing another POST request to the registered error page, whereas I expected a GET request to be performed always. Is it possible to alter this behaviour?

EDIT:

I am using the following code to configure my error page:

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {

   return (container -> {
        ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/weblogin");
        ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
        ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");

        container.addErrorPages(error401Page, error404Page, error500Page);
   });
}

When I call http://server.org/users/login using e.g. a form, the procedure is the following:

1) POST request is issued to the Server at http://server.org/users/login

2) Login credentials are invalid, error page 401 should be returned

3) Here I am not sure what happens next, Spring tells me in the logs that another POST request is performed to /weblogin. If I don't specify a custom error page, a POST request is performed to /error:

2016-11-19 20:10:38,827 [http-nio-80-exec-3] DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing POST request for [/weblogin]
2016-11-19 20:10:38,828 [http-nio-80-exec-3] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /weblogin

Solution

  • I believe you're using FromLogin on your security configuration.

    It would be simpler if you just:

    formLogin()
            .failureUrl("/my_failure_url")
            .failureHandler(authenticationFailureHandler);
    

    use a failure URL to navigate to your URL page on error, or/and write your on authentication handler which will be triggered on from login failure.

    That bean should implements AuthenticationFailureHandler interface and should be marked as bean using @Bean or @Component, on that bean all you have to do is to implement your logic:

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
                        throws IOException, ServletException {
                    // TODO Auto-generated method stub      
    }