我遇到了多个标签的问题。如果我从第一个选项卡注销并打开另一个选项卡,并在登录后退出,如果我回到第一个选项卡并登录我得到403.例如,第一个选项卡的注销页面已经通过spring security和thymeleaf添加到表单中:
<input type="hidden" name="_csrf" value="7b9639ba-aaae-4ed2-aad2-bb4c5930458e">
其中第二个标签的登录表单添加了不同的csrf标记。
<input type="hidden" name="_csrf" value="659324d5-ec5c-4c57-9984-dab740746285">
现在当我去第一个标签并从那里登录时,我得到了403禁止。这是有道理的,因为csrf令牌现在已经陈旧。但是我该如何解决这个问题呢?如果用户从不活动状态退出并重定向到登录页面但尝试再次登录一段时间(比如说半小时),我也会被禁止403。
答案 0 :(得分:4)
从Spring Security 3.2开始,我们有CsrfTokenRepository
接口,允许您存储您认为合适的同步器令牌,例如在数据库中。这样您就可以选择使这些令牌过期,以避免在用例中出现陈旧令牌。
如果您希望在 出错时提供更好的错误消息,则可以提供管理AccessDeniedHandler
和MissingCsrfTokenException
的自定义InvalidCsrfTokenException
实施例外,以产生更多信息。
<强>更新强>
我有一个处理所有未捕获异常的拦截器,所以我只构建了一个重新抛出与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);
}
}
答案 1 :(得分: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" />
...