3

I am encountering an issue with multiple tabs. If i logout from first tab and open another tab and after logging in and logging out if i go back to first tab and login i get 403. For example, the logout page of first tab had following added to the form by spring security and thymeleaf:

<input type="hidden" name="_csrf" value="7b9639ba-aaae-4ed2-aad2-bb4c5930458e">

where as the login form of second tab added a different csrf token.

<input type="hidden" name="_csrf" value="659324d5-ec5c-4c57-9984-dab740746285">

Now when i go to first tab and login from there i get 403 forbidden. Which makes sense since csrf token is now stale. But how do i get around this? I am also getting 403 forbidden if the user was logged out from inactivity and redirected to login page but tried logging in again only after a while, say half an hour.

TastyCode
  • 5,679
  • 4
  • 37
  • 42
  • Have you checked spring documentation at http://spring.io/blog/2013/08/21/spring-security-3-2-0-rc1-highlights-csrf-protection/. There does not seem to be a workaround for login issue. Regarding your last sentence, it appears to be due to session expiration. (Timeouts section in documentation) – mesutozer Mar 19 '14 at 22:02
  • We ran into a similar issue and resolved it using a custom `AccessDeniedHandler` (see https://stackoverflow.com/a/47399348/225217). – Brice Roncace Nov 20 '17 at 20:38

2 Answers2

4

As of Spring Security 3.2, we have the CsrfTokenRepository interface, which allows you to store the synchronizer token however you see fit, such as in a database. This gives you the option to expire those tokens however you want in order to avoid stale tokens in your use case.

If you want to provide a nicer error message when something does go awry, you can supply a custom AccessDeniedHandler implementation that manages the MissingCsrfTokenException and InvalidCsrfTokenException exceptions in order to produce a more informative message.

UPDATE:

I have an interceptor that handles all my uncaught exceptions, so I just built a little AccessDeniedHandler that rethrows the CSRF-related exceptions:

public class CustomAccessDeniedHandler extends AccessDeniedHandlerImpl {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        if(accessDeniedException instanceof MissingCsrfTokenException
                || accessDeniedException instanceof InvalidCsrfTokenException) {
            throw new ServletException(accessDeniedException);
        }
        super.handle(request, response, accessDeniedException);
    }
}
ironhardchaw
  • 149
  • 3
  • 10
  • Where do you register this handler class ? Can you show an example ? Thank you. – singe3 Feb 23 '16 at 15:24
  • It has been a long time since I worked with Spring and Spring Security, and I've since moved on to other things. I'll see if I can dig up some of my old code for you though. – ironhardchaw Feb 23 '16 at 15:29
  • Nevermind it was in the security config HTTP.authenticationEntryPoint – singe3 Feb 23 '16 at 17:08
0

The simplest approach to handling access denied errors I've used has been setting the access denied handler within your security config to redirect to your login page.

<http ...>
    <access-denied-handler error-page="/login.html" />
...
ethesx
  • 1,339
  • 5
  • 19
  • 35