我正在尝试上载。pdf文件,带有jQuery AJAX到Spring MVC 5,Spring Security 5后端在Tomcat上运行,根据Spring配置面临多个问题
注:
文件上传应该可以在没有身份验证的情况下使用
标记:
<div id="upload-modal" class="modal">
<div class="modal-content">
<h4>Upload</h4>
<form action="#" enctype="multipart/form-data">
<div class="file-field input-field">
<div class="btn">
<span>View...</span>
<input type="file" name="file" accept="application/pdf">
</div>
<div class="file-path-wrapper">
<label>
<input class="file-path validate" type="text">
</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<a href="#" class="modal-close waves-effect waves-green btn-flat">Cancel</a>
<a href="#" id="upload-bttn" class="waves-effect waves-light btn-flat btn">Upload</a>
</div>
</div>
所有请求的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);
});
});
使用jQuery AJAX上传:
$("#upload-bttn").click(function () {
var $uploadModal = $("#upload-modal");
const fileName = $uploadModal.find(".file-path").val();
const extension = fileName.substr(fileName.lastIndexOf(".") + 1);
if (extension === "pdf") {
$.ajax({
url: "/upload",
type: "POST",
data: new FormData($uploadModal.find("form").get(0)),
processData: false,
contentType: false,
success: function () {
console.log("success")
},
error: function () {
console.log("error")
}
});
} else {
M.toast({html: 'Selected file is not .pdf'});
}
});
一般配置如下所示。根据具体情况进行修改
安全初始化:
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityInitializer() {
super(SecurityContext.class);
}
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
}
应用程序初始化:
public class ApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
servletContext.getSessionCookieConfig().setHttpOnly(true);
servletContext.getSessionCookieConfig().setSecure(true);
AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
dispatcherServlet.register(WebAppContext.class);
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
}
}
Common sMultipartResolver
bean定义:
@Bean
public CommonsMultipartResolver multipartResolver(
@Value("${max.upload.size}") Integer maxNumber,
@Value("${max.size}") Integer maxSize) {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(1024 * maxSize * maxNumber);
resolver.setMaxUploadSizePerFile(maxSize);
resolver.setMaxInMemorySize(maxSize);
resolver.setDefaultEncoding("UTF-8");
try {
resolver.setUploadTempDir(new FileSystemResource(System.getProperty("java.io.tmpdir")));
} catch (IOException e) {
e.printStackTrace();
}
return resolver;
}
我记得当bean应该显式地命名为“MultipartResolver”时,有一个奇怪的Spring行为。我用上面的配置尝试了@Bean
和@Bean(“multipartResolver”)
,得到了相同的结果(尽管根据方法名称,上面的Bean被命名为“multipartResolver”)
结果:
错误500-无法处理部件,因为未提供多部件配置
标准ServletMultipartResolver bean定义:
@Bean
public StandardServletMultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
更新了ApplicationInitializer:
@Override
public void onStartup(ServletContext servletContext) {
...
servlet.setMultipartConfig(new MultipartConfigElement(
System.getProperty("java.io.tmpdir")
));
}
根据Spring文档:
确保在Spring Security筛选器之前指定MultipartFilter。在Spring Security过滤器之后指定MultipartFilter意味着没有调用MultipartFilter的授权,这意味着任何人都可以在服务器上放置临时文件。但是,只有授权用户才能提交由您的应用程序处理的文件
因为我需要允许未经身份验证的用户上载我在SecurityInitializer中尝试之前和之后的文件,结果如下
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
或
@Override
protected void afterSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
结果:
错误403
MultipartFilter中显式设置多部分解析器bean名称,但仍然没有运气
将csrf令牌添加到请求标头并不能同时用于这两种情况
意识到我错过了SecurityInitializer构造函数中额外的WebAppContext类。现在错误500消失了,但案例1出现了403。日志显示,尽管我像上面那样将其添加到标题中,但我的csrf令牌无效
试图使用csrf令牌提交表单,包括隐藏输入
经过两天的挣扎:
构造函数应同时包含安全和应用程序上下文配置类
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityInitializer() {
super(SecurityContext.class, WebAppContext.class);
}
}
应用程序上下文(WebAppContext)应包含多部分解析器bean定义
@Bean
public CommonsMultipartResolver multipartResolver(
@Value("${max.upload.size}") Integer maxNumber,
@Value("${max.size}") Integer maxSize) {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(1024 * maxSize * maxNumber);
resolver.setMaxUploadSizePerFile(maxSize);
resolver.setMaxInMemorySize(maxSize);
resolver.setDefaultEncoding("UTF-8");
try {
resolver.setUploadTempDir(new FileSystemResource(System.getProperty("java.io.tmpdir")));
} catch (IOException e) {
e.printStackTrace();
}
return resolver;
}
在我的情况下,在应用程序初始化之后,Spring中的令牌因某种原因为空,因此当Spring将客户端请求头中的令牌与CsrfFilter中的null进行比较时,Spring返回错误403。我在安全上下文中以以下方式配置了csrf:
@Override
protected void configure(HttpSecurity http) throws Exception {
...
http.csrf().csrfTokenRepository(new CookieCsrfTokenRepository());
...
}
现在
csrf
令牌在cookie中传递,第一个服务器响应浏览器,存储库生成并缓存一个令牌以与来自客户端的令牌进行比较,因此比较成功通过
此处,CookieCsrfTokenRepository也可以声明为CookieCsrfTokenRepository。如果您想从cookie中获取令牌并将其设置到csrf头,请使用httponlyfalse()
,但我选择了上面的元标记方法
我使用下面的代码上传一个文本文件到服务器,它可以工作。 但当我从服务器下载文本文件时,我无法打开它,并发现文本文件中添加了其他消息(粗体文本)。 --RzBVXI2AHuDiIU5UHz-A1jZrpEg6a0JY内容处理:表单数据;name=“userfile”;filename=“test.txt”内容类型:应用程序/八位字节流内容传输编码:二进制 所容纳之物 --RzBVXI2AHuDiIU
我已经迁移了所有内容并将应用程序部署到新服务器。当我尝试运行它时,我得到以下异常: 尝试使用提供程序URL获取初始上下文时发生通信故障:“corbaloc:iiop:127.0.0.1:2809”。确保URL中的任何引导地址信息正确,并且目标名称服务器正在运行。没有端口规范的引导地址默认为端口2809。除了不正确的引导地址或名称服务器不可用之外,可能的原因包括网络环境和工作站网络配置。 现在,在完
本文向大家介绍SpringMVC 文件上传配置,多文件上传,使用的MultipartFile的实例,包括了SpringMVC 文件上传配置,多文件上传,使用的MultipartFile的实例的使用技巧和注意事项,需要的朋友参考一下 基本的SpringMVC的搭建在我的上一篇文章里已经写过了,这篇文章主要说明一下如何使用SpringMVC进行表单上的文件上传以及多个文件同时上传的步骤 文件上传项目的
我试图在AWSS3中上传错误文件,但它显示错误,如“您试图访问的存储桶必须使用指定的endpoint寻址。请将所有未来的请求发送到此endpoint:”test9011960909。s3。亚马逊。com“ 我还指定了“区域”= 当我指定时,它正在工作 但我想把文件上传到主bucket的子文件夹中 我已经应用了AWS S3批准的答案:您试图访问的桶必须使用指定的终结点进行寻址 但仍然得到同样的错误,
在托管域上添加mariadb jdbc驱动程序时遇到问题,profile=full-->出现以下错误 我的当前配置 这是我使用的文件jar mariadb-java-client-2.7.1.jar
远程:对mqshaikh8/amigo.git的权限被拒绝给kshaikh99。致命:无法访问“https://github.com/mqshaikh8/amigo.git/”:请求的URL返回错误:403 git remote--V origin https://github.com/mqshaikh8/amigo.git(fetch)origin https://github.com/mqsh