如何配置Spring Security以在multipart/form-data(POST)请求中处理CSRF令牌?

0 spring-security

脚本

  • 使用HTTP API进行客户端 - 服务器通信的单页(AngluarJS)Web应用程序
  • Spring Security配置为使用CSRF保护(通过XML)
  • CSRF令牌通常在请求标头中发送(工作正常)
  • 应用程序需要支持IE9中的文件上传

问题

通过multipart/form-data POST请求实现文件上载.通常这是使用客户端AJAX完成的,但IE9不支持FileAPI(http://www.w3.org/TR/FileAPI/).

IE9的解决方法是在隐藏的iframe中创建表单,然后提交表单.CSRF令牌通过将其添加为表单输入而添加到请求正文中 - 原因是我无法操纵请求标头以在表单提交之前添加CSRF标头.

Spring Security的org.springframework.security.web.csrf.CsrfFilter首先尝试从头部获取CSRF令牌,如果没有找到,则尝试从参数中获取它(通过HttpServletRequest.getParameter())

这对于在主体中具有CSRF令牌的多部分请求不起作用 - getParameter()将始终返回null.

(顺便说一下,这个对getParameter()的调用也会将请求InputStream读取到最后,所以我们被迫在它到达CsrfFilter之前将请求换行,以便请求InputStream被'缓存')

我想创建一个调用getPart()的CsrfFilter,但是仍然使用nice + clean Spring Security XML命名空间元素时不能这样做.

原因是在配置中没有包含自定义CSRF过滤器的地方 - 并且CsrfConfigurer被硬编码为使用org.springframework.security.web.csrf.CsrfFilter,因此无法注入.

我可以将代码添加到我的请求包装器类的重写的getParameter()方法中,以尝试从多部分请求中解析参数 - 但实际上这是非常棘手的,并且宁愿避免这样的维护成本.

TL; DR

  • 我们无法添加CSRF令牌来请求头,需要添加到请求体
  • 请求是multipart/form-data
  • Spring Security CSRF过滤器不可配置为从多部分请求解析CSRF令牌

任何帮助 - 无论是在客户端还是服务器端修复建议 - 都是受欢迎的!

TIA

Rob*_*nch 5

您应该阅读讨论CSRF和Multipart请求的参考部分.您有两种选择:

每个都有其参考中描述的优点/缺点.

最后,如果要提供自定义过滤器,可以使用XML元素来实现,该元素仅引用实现Filter的Spring Bean.例如:

<http ...>
   ...
   <custom-filter ref="customCsrfFilter" position="CSRF_FILTER"/>
</http>
Run Code Online (Sandbox Code Playgroud)