Spring 安全性、Spring Webflow、文件上传和 UTF-8 问题
Issue with Spring Security, Spring Webflow, file uploads and UTF-8
我遇到的问题与这里描述的问题非常相似:,但是那个问题没有提到任何关于 UTF-8 的问题。我正在使用 Spring Framework 4.1.6、Spring Security 4.0.2 和 Spring Webflow 2.4.2.
据我所知,它围绕 StandardServletMultipartResolver
与 CommonsMultipartResolver
展开,但我不确定。如果我使用 CommonsMultipartResolver
,我可以在除 Webflow 页面之外的任何页面上上传文件,并且 UTF-8 编码在所有页面上都可以正常工作。然而,在 Webflow 页面上,尝试访问该文件时会抛出异常。如果我使用 StandardServletMultipartResolver
那么所有文件上传都可以工作,包括 Webflow,但是在任何具有 UTF-8 字符的页面上,例如 caractère,我会收到垃圾。
奇怪的是,当我使用公共解析器时,我可以在 FireBug 中看到文件正在 posted。此外,如果我调试来自 Webflow 的 RequestContext
,我还可以看到该文件在请求中深埋 4 层。通用解析器代码(标准解析器代码见post结尾):
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
MultipartHttpServletRequest multipartRequest = new DefaultMultipartHttpServletRequest((HttpServletRequest)context.getNativeRequest());
MultipartFile file = multipartRequest.getFile("file");
那么,这是 Spring 安全问题还是 Spring Webflow 问题?我怀疑如果我可以正确地转换上面的 RequestContext 公共解析器会工作,但我已经尝试了很多组合但没有运气。对此的任何指导将不胜感激。
下面是一些相关的配置和代码:
WebMvcConfig
@Bean
public CommonsMultipartResolver filterMultipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
return resolver;
}
安全配置
@Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
http
//.csrf().disable()
.addFilterBefore(characterEncodingFilter, CsrfFilter.class)
...more settings...
SecurityInitializer
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
Webflow 操作
<action-state id="uploadFile">
<evaluate expression="fileActions.uploadFile(recipe, flowRequestContext)"/>
<transition to="review"/>
</action-state>
上传文件方法
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
MultipartHttpServletRequest multipartRequest = new StandardMultipartHttpServletRequest((HttpServletRequest)context.getNativeRequest());
MultipartFile file = multipartRequest.getFile("file");
...rest of code to save the file...
事实证明,您 可以 强制转换 RequestContext 以获取底层 MultipartHttpServletRequest
但这并不漂亮。这是我最终得到的结果:
上传文件方法
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
logger.debug("uploadFile");
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
SecurityContextHolderAwareRequestWrapper wrapper1 = (SecurityContextHolderAwareRequestWrapper)context.getNativeRequest();
HttpServletRequestWrapper wrapper2 = (HttpServletRequestWrapper)wrapper1.getRequest();
FirewalledRequest firewall = (FirewalledRequest)wrapper2.getRequest();
MultipartHttpServletRequest multipartRequest = (DefaultMultipartHttpServletRequest)firewall.getRequest();
MultipartFile file = multipartRequest.getFile("file");
...rest of code to save the file...
使用它我可以保持 CommonsMultipartResolver
,无论是否使用 Webflow,应用程序中的所有文件上传都可以正常工作,而且我对 UTF-8 和字符修改没有任何问题。
我对这个解决方案不是特别满意(即使它有效),因为它依赖于将来可能会更改的特定请求嵌套(?)。我很想知道是否还有其他人 运行 遇到过相同的 UTF-8 问题以及他们是如何解决它的,但现在我要测试一下并继续前进。
我遇到的问题与这里描述的问题非常相似:
据我所知,它围绕 StandardServletMultipartResolver
与 CommonsMultipartResolver
展开,但我不确定。如果我使用 CommonsMultipartResolver
,我可以在除 Webflow 页面之外的任何页面上上传文件,并且 UTF-8 编码在所有页面上都可以正常工作。然而,在 Webflow 页面上,尝试访问该文件时会抛出异常。如果我使用 StandardServletMultipartResolver
那么所有文件上传都可以工作,包括 Webflow,但是在任何具有 UTF-8 字符的页面上,例如 caractère,我会收到垃圾。
奇怪的是,当我使用公共解析器时,我可以在 FireBug 中看到文件正在 posted。此外,如果我调试来自 Webflow 的 RequestContext
,我还可以看到该文件在请求中深埋 4 层。通用解析器代码(标准解析器代码见post结尾):
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
MultipartHttpServletRequest multipartRequest = new DefaultMultipartHttpServletRequest((HttpServletRequest)context.getNativeRequest());
MultipartFile file = multipartRequest.getFile("file");
那么,这是 Spring 安全问题还是 Spring Webflow 问题?我怀疑如果我可以正确地转换上面的 RequestContext 公共解析器会工作,但我已经尝试了很多组合但没有运气。对此的任何指导将不胜感激。
下面是一些相关的配置和代码:
WebMvcConfig
@Bean
public CommonsMultipartResolver filterMultipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
return resolver;
}
安全配置
@Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
http
//.csrf().disable()
.addFilterBefore(characterEncodingFilter, CsrfFilter.class)
...more settings...
SecurityInitializer
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
Webflow 操作
<action-state id="uploadFile">
<evaluate expression="fileActions.uploadFile(recipe, flowRequestContext)"/>
<transition to="review"/>
</action-state>
上传文件方法
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
MultipartHttpServletRequest multipartRequest = new StandardMultipartHttpServletRequest((HttpServletRequest)context.getNativeRequest());
MultipartFile file = multipartRequest.getFile("file");
...rest of code to save the file...
事实证明,您 可以 强制转换 RequestContext 以获取底层 MultipartHttpServletRequest
但这并不漂亮。这是我最终得到的结果:
上传文件方法
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
logger.debug("uploadFile");
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
SecurityContextHolderAwareRequestWrapper wrapper1 = (SecurityContextHolderAwareRequestWrapper)context.getNativeRequest();
HttpServletRequestWrapper wrapper2 = (HttpServletRequestWrapper)wrapper1.getRequest();
FirewalledRequest firewall = (FirewalledRequest)wrapper2.getRequest();
MultipartHttpServletRequest multipartRequest = (DefaultMultipartHttpServletRequest)firewall.getRequest();
MultipartFile file = multipartRequest.getFile("file");
...rest of code to save the file...
使用它我可以保持 CommonsMultipartResolver
,无论是否使用 Webflow,应用程序中的所有文件上传都可以正常工作,而且我对 UTF-8 和字符修改没有任何问题。
我对这个解决方案不是特别满意(即使它有效),因为它依赖于将来可能会更改的特定请求嵌套(?)。我很想知道是否还有其他人 运行 遇到过相同的 UTF-8 问题以及他们是如何解决它的,但现在我要测试一下并继续前进。