Spring Security 3.2、CSRF 和多部分请求

Posted

技术标签:

【中文标题】Spring Security 3.2、CSRF 和多部分请求【英文标题】:Spring Security 3.2, CSRF and multipart requests 【发布时间】:2014-09-30 21:00:56 【问题描述】:

这个问题与这个网址上的问题有关 Spring Security 3.2 CSRF support for multipart requests

我尝试了这个完全相同的设置以及要点,但除非我在 url 中有 _csrf 令牌,否则我无法让它工作。我将它作为隐藏字段放在表单正文中,并在安全过滤器之前指定了过滤器,但没有任何乐趣,并且每次都失败,并显示无效 csrf 令牌的调试日志消息

对此的任何帮助将不胜感激

达米安干杯

【问题讨论】:

它可能来自您的环境,也可能来自配置的细微差别。为了帮助缩小问题的范围,您可以从要点运行项目而没有错误吗? 我刚刚基于来自 Mkyong.com 的示例创建了一个新的示例项目,并遵循了要点。不幸的是,它仍然对我不起作用。我创建了所有相关文件的要点,位于此处gist.github.com/damogallagher/26935a84b607df3ec46b 【参考方案1】:

如果没有要点,这将很难找到,但我终于明白了!

实际上它与 Spring 安全性无关。真正的问题仅在 SpringFramework 多部分配置中。但正因为如此,请求似乎根本没有参数(_csrffile 都没有),第一个检测到它的是CsrfFilter。我删除了有关安全性的所有内容,错误是Requested parameter file absent(或类似的东西......)

如Spring Framework manual 中详述,multipart 可以通过两种方式处理:

使用 Apache 公共文件上传

使用 servlet 3.0 配置

    您遵循相关帖子的第一个解决方案并在mvc-dispatcher-servlet.xml 中配置了CommonsMultipartResolver。第一个问题是 MultipartFilter 与全局 ServletContext 相关,并在根应用程序上下文而不是 servlet 特定上下文中查找其 MultipartResolver

第二个问题是您忘记在 pom.xml 中添加对 Apache commons 文件上传的依赖。

所以你必须先在你的pom.xml中添加这个依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

接下来,您必须从 mvc-dispatcher-servlet.xml 中删除 filterMultipartResolver bean 并在根应用程序上下文中声明它。作为一个快速而肮脏的修复,您可以将其添加到spring-security.xml

<beans:bean id="filterMultipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <beans:property name="maxUploadSize" value="100000000" />
</beans:bean>
    另一种配置是使用 servlet 3.0 的多部分处理。 无需依赖 apache commons 文件上传,也无需向配置中添加任何 bean,因为 MultipartFilter 使用 StandardServletMultipartResolver 作为默认值。

您只需要在web.xml 中的DispatcherServlet 的声明中添加一个&lt;multipart-config&gt; 元素

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <multipart-config>
        <!--location>/tmp</location-->
        <max-file-size>1000000</max-file-size>
    </multipart-config>
</servlet>

【讨论】:

哇——终于有这么简单的解决方案了。非常感谢您帮助排序 我们如何在控制器中提取 MultipartFile []?我正在使用这个 MultipartRequest multipartRequest = (MultipartRequest) 请求;但得到 java.lang.ClassCastException: org.springframework.security.web.servletapi.HttpServlet3RequestFactory$Servlet3SecurityContextHolderAwareRequestWrapper 不能转换为 org.springframework.web.multipart.MultipartRequest

以上是关于Spring Security 3.2、CSRF 和多部分请求的主要内容,如果未能解决你的问题,请参考以下文章

在 spring-security 中更改 csrf 令牌

spring security4.2 配置CSRF防御场景

使用 Spring Security 的 CSRF 保护

使用 Spring Security 的 CSRF 保护

在 Spring Security 中启用 CSRF 时,访问被拒绝 403

Spring-Security对CSRF攻击的支持