Webflux multipart/form-data,启用 csrf,有或没有文件上传获取无效的 CSRF 令牌

2024-04-16

禁用 csrf 后,我可以上传文件,但我需要启用它。 仅当表单 enctype 为 multipart/form-data 时,即“无效的 CSRF 令牌”为 403 时,才会出现此问题。

一般来说,当我将 enctype 设置为 multipart/form-data 时,即使对于没有文件上传的表单,我也会收到相同的错误。

使用此依赖项:

<dependency>
  <groupId>org.synchronoss.cloud</groupId>
  <artifactId>nio-multipart-parser</artifactId>
  <version>...</version>
</dependency>

尝试在表单中包含隐藏的 csrf 输入,并尝试将其附加到 url 但同样的错误

    <form  method="post" th:action="${'/add/' + id + '/documents?' + _csrf.headerName + '=' + _csrf.token}"  enctype="multipart/form-data">
        <input type="file" name="documents" multiple="multiple">
        <input  type="hidden"
                th:name="${_csrf.headerName}"
                th:value="${_csrf.token}" />
        <input type="hidden" name="_csrf" th:value="${_csrf.token}">
        <button class="btn btn-success btn-l">Upload</button>
    </form>

对于 csrf 注入有这样的控制器建议

@ControllerAdvice
public class SecurityAdvice {@ModelAttribute("_csrf")Mono<CsrfToken> csrfToken(final ServerWebExchange exchange) {
    final Mono<CsrfToken> csrfToken = exchange.getAttributeOrDefault(org.springframework.security.web.server.csrf.CsrfToken.class.getName(), Mono.empty());
    return csrfToken;
}

在安全方面我有以下 bean:

 @Bean
    public ServerCsrfTokenRepository csrfTokenRepository() {
        WebSessionServerCsrfTokenRepository repository =
                new WebSessionServerCsrfTokenRepository();
        repository.setHeaderName("X-CSRF-TK");

        return repository;
    }

并在我的 SecurityWebFilterChain 中像这样使用它:

.and().csrf().csrfTokenRepository(csrfTokenRepository())

UPDATE:

禁用几个 url 的 csrf 也足够了。找到了一些示例,但它们都是基于 Servlet 的版本。https://sdqali.in/blog/2016/07/20/csrf-protection-with-spring-security-and-angular-js/ https://sdqali.in/blog/2016/07/20/csrf-protection-with-spring-security-and-angular-js/


看看Spring Security官方的推荐:https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-multipart https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-multipart

基本上有两种方法可以做到这一点:(1) 将 MultipartFilter 放置在 Spring Security 过滤器之前,(2) 在表单操作中包含 CSRF 令牌,就像您所做的那样。第一个选项是推荐的:

第一个选项是确保指定了 MultipartFilter 在 Spring Security 过滤器之前。指定多部分过滤器 Spring Security过滤器之前表示没有授权 用于调用 MultipartFilter 这意味着任何人都可以放置 服务器上的临时文件。但是,只有授权用户才能 能够提交由您的应用程序处理的文件。在 一般来说,这是推荐的方法,因为临时文件 上传对大多数服务器的影响可以忽略不计。

为了确保 MultipartFilter 在带有 java 配置的 Spring Security 过滤器之前指定,用户可以覆盖 beforeSpringSecurityFilterChain ,如下所示:

public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
        insertFilters(servletContext, new MultipartFilter());
    }
}

为了确保在具有 XML 配置的 Spring Security 过滤器之前指定 MultipartFilter,用户可以确保将 MultipartFilter 的元素放置在 web.xml 中的 springSecurityFilterChain 之前,如下所示:

<filter>
    <filter-name>MultipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>MultipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

请注意,如果您仍然想使用表单操作,则查询参数可能会泄漏。尝试将“headerName”更改为“parameterName”:

<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">

EDIT:如果您无法切换到基于 servlet 的容器(例如 Jetty 或 Tomcat)并且表单操作建议不起作用,最近有一个堆栈溢出线程 https://stackoverflow.com/questions/21514074/spring-csrf-token-does-not-work-when-the-request-to-be-sent-is-a-multipart-requ/43122490#43122490讨论这个问题。

一位开发人员报告使用 AJAX 解决了该问题:

我通过以下方式解决了这个问题:

  • 使用 vanilla javascript 发送多部分文件,例如Mozilla 的指南 https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript#Dealing_with_binary_data
  • 在 HTML 标头中的元中添加 _csrf 标记 标签,就像 Spring 指南中的使用 Ajax 发送 CSRF 令牌 https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf-include-csrf-token-ajax
  • 不使用jquery,直接将其添加到XHR对象中

var csrfToken = $("meta[name='_csrf']").attr("content"); var csrfHeader = $("meta[name='_csrf_header']").attr("content"); XHR.setRequestHeader(csrfHeader, csrfToken); XHR.setRequestHeader('Content-Type','multipart/form-data; boundary=' + boundary); XHR.send(data);

同一开发商将此问题报告给 Spring https://github.com/spring-projects/spring-security/issues/4265,但还没有引起人们的注意。

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

Webflux multipart/form-data,启用 csrf,有或没有文件上传获取无效的 CSRF 令牌 的相关文章

随机推荐

  • 帮助构建 boost asio ssl 示例

    我一直在研究 asio ssl 示例 链接如下 尽管尽了最大努力 我还是无法将 openssl 链接到 boost 示例中 ld 的输出是 ld 缺少 libssl a 中的符号 我无法弄清楚的是 我发现 libssl a 中带有 nm 的
  • cudaMemcpyToSymbol 的问题

    我正在尝试复制到恒定内存 但我不能 因为我对 cudaMemcpyToSymbol 函数的用法有误解 我正在努力追随this http developer download nvidia com compute cuda 4 1 rel t
  • 在 Scala 中是否有更好的方法来提升 PartialFunction?

    我偶尔会遇到以下模式 我基本上有一个PartialFunction SomeType AnotherType 并希望将其视为Function SomeType Option AnotherType eg def f s SomeType O
  • jQuery:有一种方法可以将颜色(色调)应用于图像吗?

    有没有一种方法可以使用 jQ 或某些插件对图像进行着色 应用色调 谢谢 我能想到的最简单的方法是在图像上覆盖一个半透明的 div 一个小例子 HTML div class overlay div img src img jpg CSS ov
  • 使用 ADODB 记录集执行联接更新查询

    在下面的代码中 我想将 ADODB 记录集 rs3 连接到表 tblValueChain10 并根据 ADODB 记录集 rs3 中提取的值更新 3 个不同的列 目前 更新查询未返回任何内容 Dim st Sql3 As String Di
  • Metro IndexedDB,浏览数据库

    我正在尝试使用 IndexedDB 将数据存储在 Windows 8 的 Metro 应用程序中 我希望能够浏览数据库 以监视我的操作是否按预期修改数据 所以我的问题是 有没有办法查看地铁应用程序 IE10 的实际数据库 类似于 Chrom
  • 使用“->”运算符时保留访问权限

    我有两节课 template
  • 使地图或列表在 Web UI 中可观察

    我可以通过在 Dart 代码中使用 observable 声明来使 String 或 num 类型可观察 observable var x and html 中的语法 div x x div But observable不适用于列表和地图
  • Web 部署任务在 Web 部署中失败

    我在将网站部署到域时遇到问题 它是在线的 但正在使用实体框架复制数据库中的条目 我删除了它以重新分配离线网站 但当我部署时出现错误 我尝试清理解决方案并重建 但它不起作用 它在部署时抛出异常 Web 部署任务失败 未知的 ProviderO
  • 这是向 Cocoa 中的 NSCombobox 添加项目的正确方法吗?

    我是 Delphi 程序员 对 Cocoa 很陌生 起初我尝试了这个 void awakeFromNib int i NSString mystr for i 1 i lt 24 i comboHour addItemWithObjectV
  • Oracle:如何调用重载过程?

    如何正确拨打电话DBMS OBFUSCATION TOOLKIT DESEncrypt 如果可能 不使用 PL SQL select DBMS OBFUSCATION TOOLKIT DESEncrypt x y from dual 不起作
  • 如何shell到另一个应用程序并让它以delphi形式出现

    在 Delphi 中 我多年来一直使用 ShellExecute 来启动 并可选择等待 其他应用程序 但现在 我需要让这些应用程序之一出现在我的 Delphi 应用程序表单之一中 我尝试使用下面的代码作为一个简单的测试来打开记事本 它会这样
  • 制作一个 JPanel 正方形

    如果我有一个包含多个子组件的 JPanel 我该如何制作才能使 JPanel 保持正方形 无论其父组件的大小如何调整 我尝试了以下代码的变体 但它不会导致子组件也是正方形的 public void paint Graphics g if t
  • Pandoc Filter 为链接添加脚注

    我只是想问是否有人知道 Pandoc 的一个简短过滤器 可以自动向任何链接添加脚注 我只想在我的打印文档中有可读的链接源 所以为了指定 我想从 link url 对于类似的东西 link url link url 因此 在打印的 PDF 中
  • 在 ASP Classic 中注释代码

    我所知道的散列代码的方式ASP经典版 http en wikipedia org wiki Active Server Pages is 这是正确的吗 或者还有别的办法吗 使用单引号 例如 This is comment ASP 经典使用V
  • 检测可移动驱动器(例如 USB 闪存驱动器)C/C++

    如何检测可移动磁盘驱动器何时与系统连接 断开 如何获取挂载路径 对于Linux 和驱动器号 对于Windows 编辑 有没有办法检测当前连接的设备 对于 Windows API注册设备通知 http msdn microsoft com e
  • 如何管理视图控制器可能无休止地推送到导航控制器堆栈上的情况? iOS系统

    我有一个由 UINavigationController 组成的应用程序 它从 3 个不同的选项卡推送 ViewController 我预见到的麻烦是当前的结构允许用户无休止地将 VC 添加到堆栈中 我有一个称为药物的选项卡 另一个称为病原
  • 如何在不使用 BOM 且以非 ASCII 字符开头的情况下识别文件的不同编码?

    我在尝试识别不带 BOM 的文件的编码时遇到问题 特别是当文件以非 ASCII 字符开头时 我发现以下两个关于如何识别文件编码的主题 如何在不使用 BOM 的情况下识别不同的编码 https stackoverflow com questi
  • 添加到画布后更改文本

    在fabric js中 我正在制作矩形组和文本字段 然后将其添加到画布中 我正在使用以下代码 但是一旦将文本字段添加到画布中 我可以更改文本字段的文本吗 我做了小提琴请检查 http jsfiddle net HAb4N 5 http js
  • Webflux multipart/form-data,启用 csrf,有或没有文件上传获取无效的 CSRF 令牌

    禁用 csrf 后 我可以上传文件 但我需要启用它 仅当表单 enctype 为 multipart form data 时 即 无效的 CSRF 令牌 为 403 时 才会出现此问题 一般来说 当我将 enctype 设置为 multip