spring 如何使用 _csrf 参数或 X-CSRF-TOKEN 标头在内部验证 csrf 令牌?

Posted

技术标签:

【中文标题】spring 如何使用 _csrf 参数或 X-CSRF-TOKEN 标头在内部验证 csrf 令牌?【英文标题】:How does the spring internally validate the csrf token with _csrf parameter or X-CSRF-TOKEN header? 【发布时间】:2019-02-03 16:48:03 【问题描述】:

我正在使用 spring 并通过 HttpSessionCsrfTokenRepository 启用 csrf,我清楚地知道客户端是否将 csrf 令牌作为 _csrf 参数或 X-CSRF-TOKEN 标头发送请求 spring 拾取令牌并使用令牌进行验证使用generateToken(HttpServletRequest request) 生成 但我的问题是 spring 如何在内部做到这一点。 我提出这个问题的原因是:

1.我有一个 Rest POST 调用,它接受凭据并验证 用户的身份。但是由于我想将 csrf 令牌添加到 休息调用作为安全层我想将它添加到帖子正文中 以防止 csrf 令牌泄漏。

因此,如果我知道 Spring Security 如何在内部过滤这些令牌,那将会很有帮助。我修改了 spring 文档,但主要是我们如何在带有隐藏字段或元标记的表单中使用 CSRF 令牌以及带有标题的 Ajax 调用。

而且我也想听听我的设计中的任何 cmets,如果将令牌放在正文中是好的(我深信不疑,因为泄漏令牌不是简单的 url 参数)或者我应该将它放在标题。我只是不想因为它简单而倾向于使用标题。寻找最佳解决方案。

请多指教。

【问题讨论】:

【参考方案1】:

如果你想研究的话,CsrfTokenRepository 在春天有多种实现。例如:

https://github.com/rwinch/spring-security/blob/master/web/src/main/java/org/springframework/security/web/csrf/HttpSessionCsrfTokenRepository.java

https://github.com/rwinch/spring-security/blob/master/web/src/main/java/org/springframework/security/web/csrf/CsrfFilter.java

https://github.com/rwinch/spring-security/tree/master/web/src/main/java/org/springframework/security/web/csrf

https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/apidocs/org/springframework/security/web/csrf/CookieCsrfTokenRepository.html

https://docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/apidocs/org/springframework/security/web/csrf/CookieCsrfTokenRepository.html

由于我能想到的几个原因,IMO 将令牌保留在标题上是件好事(更安全 - 可能吗?)。

    您不能在 GET 请求的正文上设置令牌。您希望所有端点保持一致(您今天可能不需要它,但情况变化非常快)

    明天如果你想改变你的 Auth 模型,你不想改变你的请求正文。当请求正文发生更改时,您会违反与客户的合同

    如果您将身份验证模型更改为授权服务器,您可以在您的服务之前添加代理服务器(如 ngnix?)并将其称为身份验证代理。您可以将所有与安全相关的内容留给此 auth-proxy,它将检查标头并为您进行验证。您不希望代理查看您的请求正文,您可以专注于您的业务实施

    请求正文与您的业务完全相关,因此您可以专注于它而不是处理您正文中与安全相关的事情。 每次为新端点创建新请求时,您都不想在所有请求中继续添加令牌

这只是我根据我的经验得出的看法。

【讨论】:

在所有这些实现中,我只能看到加载、生成和保存方法。实际令牌拦截发生在哪里。我的意思是在所有这些实现中都有参数和标题的属性,只有它们由 spring 解释。如果我在正文中添加,则禁止该请求。而且我还想知道 _csrfToken 的隐藏输入如何在 jsp 中以一种形式工作,该形式将成为 POST 正文的一部分 你能看看这个吗? docs.spring.io/spring-security/site/docs/4.2.7.RELEASE/apidocs/… @venkatReddi 你能再看看我的回答中的一些参考资料吗? CsrfFilter 是有帮助的答案

以上是关于spring 如何使用 _csrf 参数或 X-CSRF-TOKEN 标头在内部验证 csrf 令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何在单页应用(spring security)中提供 CSRF Token?

如何使用自定义登录页面纠正 Spring Security 异常?

如何通过Jqgrig请求发送Spring Security csrf

Spring MVC 4 AngularJS 1.3 HTTP POST 具有空 CSRF 令牌或标头

尝试上传时 CSRF 令牌 Spring 4 MVC 无效

Spring 未在响应时发送 CSRF 令牌