简体   繁体   English

在spring security中使用CSRF令牌获取403

[英]Getting 403 with CSRF token in spring security

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: 如果我从第一个选项卡注销并打开另一个选项卡,并在登录后退出,如果我回到第一个选项卡并登录我得到403.例如,第一个选项卡的注销页面已经通过spring security和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. 第二个选项卡的登录表单添加了不同的csrf标记。

<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. 现在,当我去第一个标签并从那里登录时,我得到403禁止。 Which makes sense since csrf token is now stale. 这是有道理的,因为csrf令牌现在已经陈旧。 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. 如果用户从不活动状态退出并重定向到登录页面但尝试再次登录一段时间(比如半小时),我也会被禁止403。

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. 从Spring Security 3.2开始,我们有了CsrfTokenRepository接口,它允许您存储您认为合适的同步器令牌,例如在数据库中。 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. 如果你要提供的东西时出差错一个更好的错误信息,您可以提供一个定制AccessDeniedHandler管理实施MissingCsrfTokenExceptionInvalidCsrfTokenException例外,以产生更翔实的信息。

UPDATE: 更新:

I have an interceptor that handles all my uncaught exceptions, so I just built a little AccessDeniedHandler that rethrows the CSRF-related exceptions: 我有一个处理所有未捕获异常的拦截器,所以我只构建了一个重新抛出与CSRF相关的异常的AccessDeniedHandler:

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

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" />
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM