一尘不染

Spring Security 3.2 CSRF对多部分请求的支持

spring

几年来我们一直在我们的应用程序中使用Spring Security。上周,我们将Spring Security从3.1.4版本升级到了3.2.0。升级进行得很好,并且升级后我们没有发现任何错误。

在浏览Spring Security 3.2.0文档时,我们发现了CSRF保护和安全标头周围的新增功能。我们按照Spring Security 3.2.0文档中的说明为受保护的资源启用CSRF保护。它适用于常规表单,但不适用于我们应用程序中的多部分表单。提交表单时,CsrfFilter由于请求中不存在CSRF令牌(通过DEBUG日志确定)而引发“拒绝访问”错误。我们尝试使用Spring Security文档中建议的第一个选项使CSRF保护与多部分表单一起使用。我们不希望使用第二个建议的选项,因为它会通过URL泄漏CSRF令牌并带来安全风险。

基于文档的配置的相关部分可以在Github上的Gist中找到。我们正在使用Spring 4.0.0版本。

请注意,我们已经尝试了以下变体而没有成功:

  1. 没有声明MultipartFilterin web.xml
  2. 没有为MultipartFilterin 设置解析器bean名称web.xml
  3. 使用默认的解析器bean的名字filterMultipartResolverwebContext.xml
    更新:我已经确认,所记录的行为即使对于单页示例应用程序也不起作用。任何人都可以确认所记录的行为按预期进行吗?有没有可以使用的示例工作应用程序?

阅读 513

收藏
2020-04-13

共1个答案

一尘不染

我能够在Spring Security团队的帮助下解决此问题。我已经更新了要点,以反映有效的配置。我必须按照下面给出的步骤进行操作,以使所有功能都能按预期工作。

1.常用步骤

添加一个MultipartFilterweb.xml以确保在Spring Security配置之前添加它:

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

<filter>
    <display-name>springSecurityFilterChain</display-name>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>ERROR</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

2.1。使用Apache Commons Multipart解析器

确保filterMultipartResolver在根Spring应用程序上下文中有一个名为Apache Commons Multipart Resolver的bean 。我将再次强调这一点,确保在Spring Spring根目录(通常称为applicationContext.xml)中声明了Multipart Resolver。例如,

web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath*:springWebMultipartContext.xml
    </param-value>
</context-param>

springWebMultipartContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="100000000" />
    </bean>
</beans>

确保该Bean称为filterMultipartResolver,因为在中未MultipartFilter配置任何其他Bean名称web.xml。我的初始配置无法正常工作,因为此bean名为multipartResolver。我什至尝试将Bean名称传递给MultipartFilterusing,web.xml init-param但这也不起作用。

2.2。使用Tomcat Multipart支持

Tomcat 7.0+具有内置的多部分支持,但必须明确启用它。context.xml如下更改全局Tomcat 文件,或context.xml在WAR文件中包括本地文件,以使该支持有效,而无需对应用程序进行任何其他更改。

<Context allowCasualMultipartParsing="true">
    ...
</Context>

在使用Apache Commons Multipart Resolver进行了这些更改之后,到目前为止,我们的应用程序可以在Tomcat,Jetty和Weblogic上运行。

2020-04-13