带有 enctype="multipart/form-data" 的 Spring Security CSRF [重复]

Posted

技术标签:

【中文标题】带有 enctype="multipart/form-data" 的 Spring Security CSRF [重复]【英文标题】:Spring Security CSRF with enctype="multipart/form-data" [duplicate] 【发布时间】:2015-03-04 04:45:31 【问题描述】:

我在jsp文件中有这个表格:

<form:form method="POST" commandName="advertForm" onsubmit="return checkAddress();" enctype="multipart/form-data">

<form:errors path="*" cssClass="errorblock" element="div"/>

<table>
    <tr>
        <td>Text:</td>
        <td><form:input path="advert.text"/></td>
        <td><form:errors path="advert.text" cssClass="error"/></td>
    </tr>
    <table id="fileTable">
        <tr>
            <td><input name="images[0]" type="file" /></td>
        </tr>
        <tr>
            <td><input name="images[1]" type="file" /></td>
        </tr>
    </table>
    <tr>
        <td colspan="1"><a style="text-decoration: none" href="/"><input type="button" value="Cancel"/></a></td>
        <td colspan="2"><input type="submit" value="Save"/></td>
    </tr>
      <input type="hidden"
             name="$_csrf.parameterName"
             value="$_csrf.token" />
</table>
</form:form>

还有这个 AdvertForm 类:

public class AdvertForm 
    private Advert advert;
    private List<MultipartFile> images;

    public Advert getAdvert() 
        return advert;
    

    public void setAdvert(Advert advert) 
        this.advert = advert;
    

    public List<MultipartFile> getImages() 
        return images;
    

    public void setImages(List<MultipartFile> images) 
        this.images = images;
    

在相应的控制器中我使用这个参数接收数据:

@ModelAttribute("advertForm") AdvertForm advertForm

问题是,当 sping-security.xml 中的 csrf 被禁用时,它可以正常工作 - 我可以在 advertForm.getImages() 中看到选择的文件,但是当我启用 csrf 时,它会停止使用:

Invalid CSRF token found for http://localhost:8080

我尝试通过以下步骤解决此问题:

    我在 securityFilterChain 之前添加了多部分过滤器:

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

    我定义了 filterMultipartResolver: &lt;bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"&gt; &lt;property name="maxUploadSize" value="100000000" /&gt;&lt;/bean&gt;

并将其添加到 web.xml:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        ......,
        /WEB-INF/springWebMultipartContext.xml
    </param-value>
</context-param>

    在 Tomcat 7 中启用 CasualMultipartParsing(我使用独立库从 IDE 运行)

    ctx.setAllowCasualMultipartParsing(true)

现在表单可以工作了 - 我没有收到任何 csrf 错误。但是当控制器接收到 advertForm 参数时,advertForm.getImages() 返回 null,而 advertForm.getText() 返回用户输入的文本。在日志中我可以看到这一行:

DEBUG  CommonsMultipartResolver - Found multipart file [images[0]] of size 3117 bytes with original filename [11111111.txt], stored in memory

我的错误在哪里?

【问题讨论】:

【参考方案1】:

我忘了说我定义了这个 bean:

<bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

这是个问题。删除此 bean 后一切正常。

【讨论】:

以上是关于带有 enctype="multipart/form-data" 的 Spring Security CSRF [重复]的主要内容,如果未能解决你的问题,请参考以下文章

排除在“enctype=‘multipart/form-data’”之外的MultipartException

Django 表单:当文件发布到带有 enctype 的文件字段时,“此字段是必需的”

php 文件上传

method="post" enctype="text/plain" 不兼容?

表格 enctype "application/json" 可用吗?

C# form表单提交enctype="multipart/form-data" 与 enctype="application/x-www-form-urlencoded