尽管以表单形式发送 CSRF 令牌,但不支持 Spring Security CSRF 405 方法 POST

Posted

技术标签:

【中文标题】尽管以表单形式发送 CSRF 令牌,但不支持 Spring Security CSRF 405 方法 POST【英文标题】:Spring Security CSRF 405 Method POST not supported inspite of sending CSRF token in form 【发布时间】:2018-02-24 04:35:50 【问题描述】:

我正在使用 Spring 框架版本 4.3.5.RELEASE。 Spring 安全版本是 4.2.2.RELEASE。

我遇到了一个与 CSRF 相关的奇怪问题。每当我提交表单(来自 JSP 文件)时,有时它工作正常,表单提交时没有错误,但有时在提交表单后,它显示 Http Status 405 ?方法不支持。我也包含了 csrf 令牌,既包含在隐藏字段中,也包含在表单操作标签中的查询字符串中。

这是我项目中的一个示例 POST 表单:

 <form:form class="form-horizontal" method="POST" modelAttribute="dealerVisit" enctype="multipart/form-data" 
        action="http://localhost:8080/update/edit.html?$_csrf.parameterName=$_csrf.token">

        <input type="hidden" name="$_csrf.parameterName" value="$_csrf.token">
</form:form>

这是我提交上述表单的控制器:

@RequestMapping(value = "/update/edit.html", method = RequestMethod.POST)
    public String saveEdit(ModelMap map, @Valid @ModelAttribute(MODEL_KEY) DealerVisitVO dealerVisitVO, BindingResult result,
            @RequestParam(required = false, name="followup") Boolean followup) 
//my codes here

问题是随机出现的。有时有效,有时无效。代码或形式没有变化。禁用 CSRF 不是一个可行的解决方案,因为这是我的客户的一项要求。

如果有人能解决,请帮忙。

【问题讨论】:

您能否更好地解释为什么您认为这与 CSRF 有关。 HTTP 405 的响应并不意味着 CSRF 问题。 405 仅表示服务器不支持此资源的 HTTP 方法(POST、GET 等)。见tools.ietf.org/html/rfc7231#section-6.5.5。 如果你能看到我的表单的method 属性,它被设置为POST。在我的控制器的RequestMapping 上指定了相同的POST 类型。此外,当我禁用 CSRF 时,问题永远不会出现。因此,它与 CSRF 有关。另外,在发布问题之前,我已经对这个问题进行了很多搜索,所有内容都指向 Spring 安全性的 CSRF 问题。 我面临同样的问题..希望永久解决方案,除了禁用 CSRF 如果客户端没有按时调用,可能是 csrf 令牌过期。调试它。 :-) 【参考方案1】:

在 Spring Security 中,CSRF 令牌在每个会话的基础上生成,并且在您的会话未过期之前保持不变。这是一种不允许使用 405 方法的情况,因为您的会话将在某个时间间隔到期(您可以检查一下)。其次,如果您使用的是 spring 的形式,则无需显式地将令牌放入隐藏字段,spring 默认会这样做,也无需将其放入查询字符串中。你的代码应该是这样的...

<form:form class="form-horizontal" method="POST" modelAttribute="dealerVisit" enctype="multipart/form-data" action="http://localhost:8080/update/edit.html">

     <!-- Spring will add by default -->
    <!-- <input type="hidden" name="$_csrf.parameterName" value="$_csrf.token"> -->

【讨论】:

如何处理令牌过期并显示自定义错误页面的情况?

以上是关于尽管以表单形式发送 CSRF 令牌,但不支持 Spring Security CSRF 405 方法 POST的主要内容,如果未能解决你的问题,请参考以下文章

如何生成和验证 csrf 令牌

何时需要使用令牌保护表单(CSRF 攻击)?

具有多种形式的网页上的 CSRF 令牌?

更改提交时 Ajax 表单上的 CSRF 令牌不匹配

带有 CSRF 令牌和会话的 Symfony 4 功能形式测试

反应形式 CSRF 安全