spring security下fileupload上传文件被拦截

原创 2016年08月28日 16:33:41

fileupload插件github网址
fileupload插件jQuery网站
spring mvc+fileupload例子

好了,从刚开始引入js文件的时候就入了坑:

<script src="js/jquery.1.9.1.min.js"></script>
<script src="js/jquery.fileupload.js"></script>
<script src="js/vendor/jquery.ui.widget.js"></script>
<script src="js/jquery.iframe-transport.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<link href="bootstrap/css/bootstrap.css" type="text/css" rel="stylesheet" />

我引入的时候按照以上顺序!!后来发现直接找不到方法:

$('#file').fileupload();

才发现要按照以下顺序:

<script src="js/jquery.1.9.1.min.js"></script>
<script src="js/vendor/jquery.ui.widget.js"></script>
<script src="js/jquery.iframe-transport.js"></script>
<script src="js/jquery.fileupload.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<link href="bootstrap/css/bootstrap.css" type="text/css" rel="stylesheet" />

把jquery.fileupload.js放在最后面,这样才能在里面引用到其他js文件。


那么在Security里要post数据,必须要有csrf的token,否则一定会有403拒绝访问的壁要碰的 ……
有三种方法:
1. 直接将multipartfilter置于springSecurityFilterChain之上,这样就上传文件的时候就会先被multipartfilter拦截,而不会受到security的保护:
重写此方法:

public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
        insertFilters(servletContext, new MultipartFilter());
    }
}

在xml配置中确保MultipartFilter 被放在springSecurityFilterChain之前:

<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>

这样,简单粗暴的解决了(当时这样,谁都可将文件上传到服务器,被短暂的保存起来,只有被授权的用户才可以上传一个被应用处理的文件。在大多数情况下,这些暂时被保存的文件不会有太大的问题,因为框架会定期自动清理。)


2.将csrf的token作为url参数:

<html>
<head>
    <meta name="_csrf" content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" content="${_csrf.headerName}"/>
    <!-- ... -->
</head>
<!-- ... -->
<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">

但是这样就导致token泄露了。
如果放到hidden区域里:

<input type="hidden"
    name="${_csrf.parameterName}"
    value="${_csrf.token}"/>

可能因为commons-fileupload组件对request进行封装的时候对csrf的支持有问题,没有传递csrf值。所以被over掉了…….


  1. 用AjaxUpload上传:
var uploader = new AjaxUpload({
        url: '/file/upload',
        name: 'uploadfile',
        multipart: true,
        customHeaders: { '${_csrf.headerName}': '${_csrf.token}' },
        ...
        onComplete: function(filename, response) {
            ...
        },
        onError: function( filename, type, status, response ) {
            ...
        }
});

但是网上没有找到此插件…….pass掉


4.用fileupload插件:

$('#file').fileupload({
                    dataType: 'json',
                    add: function (e, data) {
                        data.context = $('<button/>').text('Upload')
                                .appendTo(document.body)
                                .click(function () {
                                    data.context = $('<p/>').text('Uploading...').replaceAll($(this));
                                    data.submit();
                                });
                    },
                    done: function (e, data) {
                        data.context.text('Upload finished.');
                    }
                });

但是在jquery.fileupload.js里找了好久,发现了一个方法:_initXHRData: function (options) 跟设置request headers有点关系。可是怎么讲csrf的header和token传进去呢?!后来想到我可以直接用ajaxSend先设置requestHeader不就行了!!!
解决Spring Security 表单上传文件CSRF失效的问题

$(document).ready(function() {
            var token = $("meta[name='_csrf']").attr("content");
            var header = $("meta[name='_csrf_header']").attr("content");
            $(document).ajaxSend(function(e, xhr, options) {
                xhr.setRequestHeader(header, token);
            });
            $('#file').fileupload({
                    dataType: 'json',
                    add: function (e, data) {
                        data.context = $('<button/>').text('Upload')
                                .appendTo(document.body)
                                .click(function () {
                                    data.context = $('<p/>').text('Uploading...').replaceAll($(this));
                                    data.submit();
                                });
                    },
                    done: function (e, data) {
                        data.context.text('Upload finished.');
                    }
                });
<body>
    <div>
        <input type="file" name="file" id="file" data-url="/upload" /><br/>
    </div>
</body>

就酱紫,折腾了半天文档,还是用这种方法解决了!!!
PS:如果用的是thymeleaf模板,注意用的是:th:content

<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta name="_csrf" th:content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
</head>

参考:stackoverflow上类似解决方法
stackoverflow另一个网址

另外付一个用JSP的Taglib解决方法

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
    <form method="post" action="/do/something">
        <sec:csrfInput />
        Name:<br />
        <input type="text" name="name" />
        ...
    </form>
    还有一个:<sec:csrfMetaTags />方法。
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

解决Spring Security 表单上传文件CSRF失效的问题

在Spring Security4中引入的CSRF是不错的安全机制. 但在常用的上传文件中(form提交, post, 使用commons-fileupload)会导致CSRF失效, 这问题的根源在...

shiro安全框架扩展教程--上传文件的安全控制

相信每一个项目都会存在文件上传功能,最常见的就是图片,音频,视频等上传,但是如果用户多的应用都会存在用户恶意上传动作,包括伪装成可上传文件, 按照我们以往的方式,普通地判断后缀名,那是不可行,除了一...

uploadify上传失败,出现security错误

uplodify使用flash跨域上传文件会出现上传失败的情况,只是由于flash的限制所致。跨域即文件服务器的域名或者ip与应用服务器的域名或者ip不一致,解决的方法如下: 在应用程序的Web...

JAVABEAN是什么和总结JAVABEAN的两种使用方式

原文:http://www.blogjava.net/flysky19/articles/88180.html 一、 javabean 是什么? Javabean 就是一个类,这个类就定义一系列 g...

Servlet学习笔记(八):过滤器Filter详解

1、Filter,过滤器,用于在servlet之外对request 和response 进行修改。Filter 有一个 FilterChain 的概念,一个FilterChain 包括多个 Filte...

HTML5 下利用 csrf 上传文件

看到这篇文章: 利用 csrf 漏洞上传文件 . Q1: 怎样构造一个实际有效的例子; Q2: 怎样检测这种漏洞; 直接将文中的 payload 写入一个 html 文件, 用浏览器加载, 并...

kindeditor上传文件在SpringMVC中servletFileUpload.parseRequest(request)解析为空获取不到数据问题 .

版权声明:本文为博主原创文章,未经博主允许不得转载。最近用kindeditor做上传文件,老是在List items = upload.parseRequest(request);取不到值,查了一些资...

Java-上传文件Spring MultipartResolver 或者 ServletFileUpload

在Java开发过程中,如果我们想开发上传功能,那么有两种方法可以解决:   使用Spring框架中的MultipartResolver   使用原生的代码ServletFileUpload ...

Spring MVC 4 使用常规的fileupload上传文件(带源码)

【本系列其他教程正在陆续翻译中,点击分类:spring 4 mvc 进行查看。源码下载地址在文章末尾。】 【翻译 by 明明如月 QQ 605283073】 上一篇:  Spri...

使用common-fileUpload和 Spring中MultipartHttpServletRequest实现文件上传

一、上传对表单的要求 1) 表单的提交方式 :"method=post" 2) 表单的类型 :enctype="multipart/form-data" 3) 上传表单的文件项:xx" /> /.....
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)