问题
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.
回答1:
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);
}
}
回答2:
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" />
...
来源:https://stackoverflow.com/questions/22517107/getting-403-with-csrf-token-in-spring-security