Spring Security 3.2 CSRF对多部分请求的支持 [英] Spring Security 3.2 CSRF support for multipart requests
问题描述
我们在应用程序中使用Spring Security已有几年了.上周,我们将Spring Security从3.1.4版本升级到了3.2.0.升级进行得很好,并且升级后我们没有发现任何错误.
We have been using Spring Security with our application for a few years now. Last week we upgraded Spring Security from version 3.1.4 to 3.2.0. The upgrade went fine and we did not find any errors post the upgrade.
在浏览Spring Security 3.2.0文档时,我们发现了CSRF保护和安全标头周围的新增功能.我们按照Spring Security 3.2.0文档中的说明为受保护的资源启用CSRF保护.它适用于常规表单,但不适用于我们应用程序中的多部分表单.提交表单时,CsrfFilter
会抛出访问被拒绝"错误,原因是请求中不存在CSRF令牌(通过DEBUG日志确定).我们已经尝试使用 Spring Security文档中建议的第一个选项 a>用于使CSRF保护与多部分表单一起使用.我们不希望使用第二个建议的选项,因为它会通过URL泄漏CSRF令牌并带来安全风险.
While looking through the Spring Security 3.2.0 documentation we came across the newly added features around CSRF protection and security headers. We followed the instructions in the Spring Security 3.2.0 documentation to enable CSRF protection for our protected resources. It works fine for regular forms but does not work for multipart forms in our application. On form submission, CsrfFilter
throws an Access Denied error citing the absence of a CSRF token in the request (determined through DEBUG logs). We have tried using the first option suggested in the Spring Security documentation for making CSRF protection work with multipart forms. We do not want to use the second suggested option as it leaks CSRF tokens through the URLs and poses a security risk.
基于文档的配置的相关部分可以在Github上的 Gist 中获得.我们正在使用Spring 4.0.0版.
The relevant part of our configuration based on the documentation is available as a Gist on Github. We are using Spring version 4.0.0.
请注意,我们已经尝试了以下变体而没有成功:
Note that we have already tried the following variations without success:
- 未在
web.xml
中声明MultipartFilter
. - 未在
web.xml
中为MultipartFilter
设置解析器bean名称. - 在
webContext.xml
中使用默认的解析器bean名称filterMultipartResolver
.
- Not declaring the
MultipartFilter
inweb.xml
. - Not setting the resolver bean name for the
MultipartFilter
inweb.xml
. - Using the default resolver bean name
filterMultipartResolver
inwebContext.xml
.
更新:我已经确认,所记录的行为即使对于单页示例应用程序也不起作用.任何人都可以确认所记录的行为按预期进行吗?有可以使用的示例工作应用程序吗?
UPDATE: I have confirmed that the documented behaviour does not work even with a single page sample app. Can anyone confirm that the documented behaviour works as expected? Is there an example working application that can be used?
推荐答案
我能够在Spring Security团队的帮助下解决此问题.我已经更新了要点以反映有效的配置.为了使所有功能都能按预期工作,我必须遵循以下步骤.
I was able to resolve this with help from the Spring Security team. I have updated the Gist to reflect a working configuration. I had to follow the steps given below in order to get everything to work as expected.
1.常用步骤
按照 @ holmis83的答案所述,在web.xml
中添加MultipartFilter
,确保已添加在Spring Security配置之前:
Add a MultipartFilter
to web.xml
as described in the answer by @holmis83, ensuring that it is added before the Spring Security configuration:
<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 Resolver
确保在根Spring应用程序上下文中有一个名为filterMultipartResolver
的Apache Commons Multipart Resolver bean .我再次强调这一点,确保Multipart Resolver在根Spring Context中被声明(通常称为 applicationContext.xml ).例如,
Ensure that there is an Apache Commons Multipart Resolver bean named filterMultipartResolver
in the root Spring application context. I will stress this again, make sure that the Multipart Resolver is declared in the root Spring Context (usually called applicationContext.xml). For example,
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 ,因为web.xml
中配置的MultipartFilter
不会选择任何其他bean名称.我的初始配置无法正常工作,因为此Bean被命名为 multipartResolver .我什至尝试使用web.xml
init-param
将Bean名称传递给MultipartFilter
,但这也不起作用.
Make sure that the bean is called filterMultipartResolver as any other bean name is not picked up by MultipartFilter
configured in web.xml
. My initial configuration was not working because this bean was named multipartResolver. I even tried passing the bean name to MultipartFilter
using web.xml
init-param
but that did not work either.
2.2.使用Tomcat Multipart支持
Tomcat 7.0+具有内置的多部分支持,但必须明确启用它.如下更改全局Tomcat context.xml
文件,或者在WAR文件中包括本地context.xml
文件,以便在不对应用程序进行任何其他更改的情况下使用此支持.
Tomcat 7.0+ has in-built multipart support, but it has to be explicitly enabled. Either change the global Tomcat context.xml
file as follows or include a local context.xml
file in your WAR file for this support to work without making any other changes to your application.
<Context allowCasualMultipartParsing="true">
...
</Context>
在使用Apache Commons Multipart Resolver进行了这些更改之后,我们的应用程序目前可以在Tomcat,Jetty和Weblogic上运行.
After these changes using Apache Commons Multipart Resolver our application is working so far on Tomcat, Jetty and Weblogic.
这篇关于Spring Security 3.2 CSRF对多部分请求的支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!