无法使用 Spring Security 创建 CSRF 令牌

2023-11-27

我在 Spring MVC 应用程序中使用 Spring Security 3.2.3 并得到一些意外的行为。

根据文档在这里,应该可以使用${_csrf.token}在我的 html 的元标记中:

<meta name="_csrf" content="${_csrf.token}" />
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}" />

我使用 JQuery 从中提取“内容”的值,并使用 AJAX 将其放入请求标头中。

但出于某种原因,Spring Security 不会将其“转换”为实际令牌,它只是作为文字字符串“${_csrf.token}”发送到标头中。

尝试使用替代路线${_csrf.token}在根据文档的隐藏输入中,然后我尝试通过检查输入的值来检查令牌的计算结果,但它仍然只是纯文本“${_csrf.token}”。

由于 Spring Security 似乎未生效,我是否缺少某种配置?我目前正在使用准系统 Spring Security Java 配置(而不是 xml),如下所示:

import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.*;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .csrf();
      }
}

我知道配置被调用,因为我在其中放入了调试语句,所以我假设 CSRF 保护确实已启用,因为它应该是默认的。

我意识到语法“${}”是JSP表达式语言,我目前成功地使用它通过Thymeleaf将上下文评估为对象,例如:

th:object="${context}"

所以我尝试在元标记的“内容”前面添加“th:”,如下所示:

<meta name="_csrf" th:content="${_csrf.token}"/>

但这会导致无法评估的异常:

计算 SpringEL 表达式时出现异常:“_csrf.token”

我认为这里的关键可能是弄清楚如何让表达式在我看来正确评估。


我终于解决了这个问题,但是基本上需要重写Spring Security。它的所有荣耀都在这里。

首先,我遵循了 Eyal Lupu 精彩博客文章中的建议here,但由于我的 AJAX 要求,我必须根据我的情况进行调整。

至于 Thymeleaf 的情况,关键的花絮隐藏在 Thymeleaf 论坛的档案中 - Inknown Issue 7。

https://github.com/thymeleaf/thymeleaf-spring/issues/7#issuecomment-27643488

Thymeleaf 的创建者本人的最后评论是这样的:

th:action...检测何时将此属性应用于 标签——无论如何,这应该是唯一的地方——在这种情况下 来电RequestDataValueProcessor.getExtraHiddenFields(...) 并添加 在结束标记之前返回隐藏字段。

这是我让令牌发挥作用所需的关键短语。不幸的是,原因完全不明显th:action也将拉开序幕getExtraHiddenFields,但无论如何它确实如此,这才是重要的。

因此,对于那些在 Thymeleaf + Spring Security CSRF + AJAX POST 方面苦苦挣扎的人,以下是我的步骤(这大大简化了它,但这些是解决它的高级概念):

  1. 实现 Spring 接口 RequestDataValueProcessor 并将其注册到 Spring Security 的 XML 配置中,以便您可以重写 getExtraHiddenFields 方法,该方法允许您将隐藏输入字段插入到 HTML 中(当然需要使用令牌)。令牌本身是使用 Java.Util UUID 生成的。

  2. 使用 JQuery,从该隐藏字段读取值并设置请求标头的“X-CSRF-Token”属性,以便它通过 HTTP 发送。不可能简单地将令牌保留在隐藏输入字段中,因为我们没有执行表单提交,而是使用 AJAX POST 来调用服务器端的方法。

  3. 扩展 Spring 的 HandlerInterceptorAdapter 并将其注册为拦截器,以便每次完成 POST 方法时,都会调用服务器端的“preHandle”方法,以便它可以将请求令牌(从上一步中从 HTTP 标头中提取)与请求令牌进行比较会话的令牌(应该相同!)。完成此检查后,它可以允许请求通过或返回错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法使用 Spring Security 创建 CSRF 令牌 的相关文章

随机推荐

  • 有人可以向我解释一下 class << self 吗?

    我第一次进入 Rails 编程 在查看我下载的一些库的代码时 我偶尔会注意到这些代码 class lt lt self def func stuff end end 我尝试在网上搜索解释 但是 在红宝石中 class lt lt foo打开
  • 如何在 WP7 中将多个值数据绑定到单个 TextBlock.Text?

    如何将 2 个属性绑定到单个 TextBlock Text 例如名字和姓氏或当前值和最大值 就像是 IValueConverter public object Convert return string Format 0 max 1 cur
  • 多边形的面积(使用 Python 递归)

    我正在尝试解决 探索Python 书中的一个练习 但是 我想我不理解递归的概念 我写了一些递归函数 所以我知道一些方面 但是 我没有足够的经验 我已经停止学习编程大约一年了 无论如何 让我给你一个完整的问题 多边形可以由 x y 对列表表示
  • 通过字符串调用方法

    我有以下课程 func list function1 function2 function3 class doit object def init self for item in func list if item function1 s
  • Youtube API V3 出现错误 403 禁止

    我的 Youtube Api v3 有问题 问题是想要从上传的视频中获取信息 在执行检索视频信息时 出现错误 403 Forbidden 如果我运行我正在使用的 url 浏览器会返回包含所有视频数据的 Json Visual Studio
  • .NET - 用单个 using 语句替换嵌套的 using 语句

    如果您遇到类似这样的带有嵌套 using 语句 资源的 C 代码 using var response HttpWebResponse request GetResponse using var responseStream respons
  • 浮点运算错误

    我使用以下函数来近似函数在某一点的导数 def prime x f x h if not f x h f x and not h 0 0 return f x h f x h else raise PrecisionError 作为一个测试
  • 通过项目文件从 TFS 中排除文件

    我正在寻找从 TFS 中排除生成的 VS 项目文件的某些文件的可能性 我知道这可能是之后的 vspscc 文件 但我想要的是 在将项目添加到 TFS 之前 我可以告诉 VS 项目文件 其中的某些文件不允许添加到 TFS TFS 中有几个排除
  • jQuery 支持 CSS4 选择器吗?

    jQuery 或其他 JavaScript 库支持 CSS4 选择器吗 甚至浏览器 我如何测试它们 目前 jQuery 支持的唯一 4 级选择器是 has and 的扩展版本 not 这只是因为该规范从 jQuery 本身中汲取了灵感 因为
  • 为什么 Chrome 不断在控制台中显示“无法安装网站:该页面不是从安全来源提供的”?

    每当我查看 Chrome 的控制台时 我都会看到以下错误消息 无法安装网站 该页面不是从安全来源提供的 这种情况是在几天前才开始发生的 而 Chrome 在此期间还没有更新 2019 年 12 月更新 这个答案已经过时了 其中提到的两个标志
  • 为什么需要 HTML 字符实体?

    为什么需要 HTML 字符实体 他们有什么好处 我不明白有什么意义 主要有两件事 它们允许您使用当前字符集中未定义的字符 例如 您可以合法地使用 ASCII 作为字符集 并且仍然通过实体包含任意 Unicode 字符 正如 Simon 所指
  • 使用 Perl 的 HTTP 多部分响应

    是否可以像多部分请求一样提供 HTTP 多部分响应 场景是这样的 我想提供一个 URL 它采用 EmployeeID 参数 作为回报 响应应包含员工的照片 最新的工资单以及姓名 年龄和地址等信息 接收端不是浏览器 而是一个获取此响应并稍后处
  • bash:将某些内容回显到窗口右端(右对齐)

    我正在寻找生成在 bash 中右对齐的成功 失败消息 一个例子是 apache2 执行时产生的结果 sudo etc init d apache2 reload etc 在上面的例子中 apache2 产生的结果非常漂亮和简洁 OK or
  • C++ 正则表达式字符串捕获

    尝试让 C 正则表达式字符串捕获工作 我已经尝试了 Windows 与 Linux Boost 与本机 C 0x11 的所有四种组合 示例代码是 include
  • 如何在 SQL Server 2008 中创建序列

    我正在使用以下代码在 SQL Server 中创建序列 但它显示错误为未知对象类型 请给出解决方案 这是我的代码 create sequence seqval start with 100 increment by 1 minvalue 0
  • SqlAlchemy 在查询表对象时不返回所有行,但在查询表对象列时返回所有行

    更新 下面的解决方案 我对 SqlAlchemy 非常陌生 所以如果这是一个明显的问题 请原谅 当我查询 Table 对象时 我只得到一个结果 数据库中的第一个结果 我的过滤器有 600 多个结果 当我按表上的列查询时 它会返回我期望的所有
  • 我应该在单例上实现 IDisposable 吗?

    我有一个 Windows 服务 其中包含一个单例 该单例又使用一些记录器 消息队列侦听器等 这些类实现了IDisposable 我应该实施IDisposable在单例本身中还是做其他事情来确保服务停止 崩溃后 本机资源一切正常 单例是这样实
  • 使用 ElasticSearch JDBC River 从表中获取更改

    我正在为 ElasticSearch 配置 JDBC River 但找不到任何好的配置示例 我已阅读全部pages on 弹性搜索河jdbc GitHub 我有一个 SQL 查询 需要每 X 秒从所有表列中获取更改 我如何告诉 JDBC R
  • symfony2 获取实体上的所有验证约束(yml、xml、注释)

    我试图获取实体上的所有验证约束并将这些约束转换为 Jquery 验证规则 现在我能够获取注释定义的约束 感谢 Symfony2 获取实体的验证约束 但我在获取 xml 和 yml 时遇到一些问题 xml file loader new Xm
  • 无法使用 Spring Security 创建 CSRF 令牌

    我在 Spring MVC 应用程序中使用 Spring Security 3 2 3 并得到一些意外的行为 根据文档在这里 应该可以使用 csrf token 在我的 html 的元标记中 我使用 JQuery 从中提取 内容 的值 并使