Я использую,
- ВЫПУСК Spring Framework 4.0.0 (GA)
- Spring Security 3.2.0 ВЫПУСК (GA)
- Стойки 2.3.16
В котором я использую встроенный токен безопасности для защиты от CSRF-атак.
<s:form namespace="/admin_side"
action="Category"
enctype="multipart/form-data"
method="POST"
validate="true"
id="dataForm"
name="dataForm">
<s:hidden name="%{#attr._csrf.parameterName}"
value="%{#attr._csrf.token}"/>
</s:form>
Это составной запрос, в котором токен CSRF недоступен для безопасности Spring, если только MultipartFilter
вместе с MultipartResolver
не настроены должным образом, чтобы составной запрос обрабатывался Spring.
MultipartFilter
в web.xml
настраивается следующим образом.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<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>
<filter>
<filter-name>AdminLoginNocacheFilter</filter-name>
<filter-class>filter.AdminLoginNocacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AdminLoginNocacheFilter</filter-name>
<url-pattern>/admin_login/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>NoCacheFilter</filter-name>
<filter-class>filter.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>NoCacheFilter</filter-name>
<url-pattern>/admin_side/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<description>Description</description>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>struts.devMode</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
А в applicationContext.xml
MultipartResolver
прописывается следующим образом.
<bean id="filterMultipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="-1" />
</bean>
Токен CSRF теперь получает служба безопасности Spring, но это вызывает еще одну проблему в Struts.
Загруженные файлы теперь null
в классах действий Struts, как показано ниже.
@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value="struts-default")
public final class CategoryAction extends ActionSupport implements Serializable, ValidationAware, ModelDriven<Category>
{
private File fileUpload;
private String fileUploadContentType;
private String fileUploadFileName;
private static final long serialVersionUID = 1L;
//Getters and setters.
//Necessary validators as required.
@Action(value = "AddCategory",
results = {
@Result(name=ActionSupport.SUCCESS, type="redirectAction", params={"namespace", "/admin_side", "actionName", "Category"}),
@Result(name = ActionSupport.INPUT, location = "Category.jsp")},
interceptorRefs={
@InterceptorRef(value="defaultStack", "validation.validateAnnotatedMethodOnly", "true"})
})
public String insert(){
//fileUpload, fileUploadContentType and fileUploadFileName are null here after the form is submitted.
return ActionSupport.SUCCESS;
}
@Action(value = "Category",
results = {
@Result(name=ActionSupport.SUCCESS, location="Category.jsp"),
@Result(name = ActionSupport.INPUT, location = "Category.jsp")},
interceptorRefs={
@InterceptorRef(value="defaultStack", params={ "validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
public String load() throws Exception{
//This method is just required to return an initial view on page load.
return ActionSupport.SUCCESS;
}
}
Это происходит потому, что, по моему мнению, составной запрос уже обработан и использован Spring, следовательно, он недоступен для Struts как составной запрос, и поэтому файловый объект в классе действий Struts равен null
.
Есть ли способ обойти эту ситуацию? В противном случае у меня теперь остался единственный вариант добавить токен к URL-адресу в качестве параметра строки запроса, что крайне не рекомендуется и вообще не рекомендуется.
<s:form namespace="/admin_side"
action="Category?%{#attr._csrf.parameterName}=%{#attr._csrf.token}"
enctype="multipart/form-data"
method="POST"
validate="true"
id="dataForm"
name="dataForm">
...
<s:form>
Короче говоря: как получить файлы в классе действий Struts, если Spring создан для обработки многокомпонентного запроса? С другой стороны, если Spring не обрабатывает многокомпонентный запрос, он создает токен безопасности. Как выйти из этой ситуации?
struts2
фильтр передSpring MultipartFilter
. - person Kamil Chaber   schedule 08.02.2014struts2
перемещается перед фильтромMultipartFilter
, он жалуется на то, что проверка подлинности вызывает исключениеAn Authentication object was not found in the SecurityContext
. Кроме того,MultipartFilter
должен стоять передspringSecurityFilterChain
, иначе токен будет недоступен, если запрос состоит из нескольких частей. - person Tiny   schedule 08.02.2014struts2
с/*
на*.action
. - person Kamil Chaber   schedule 08.02.2014*.action
передается фильтруstruts2
после его перемещения передMultipartFilter
, стратегия безопасности полностью пропускается. Доступ ко всем ресурсам осуществляется публично без какой-либо аутентификации. - person Tiny   schedule 08.02.2014