Issue with Spring Security, Spring Webflow, file uploads and UTF-8

☆樱花仙子☆ 提交于 2019-12-12 05:19:13

问题


I have a problem very similar to the one described here: File Upload using Spring WebFlow 2.4.0, parameter not binded, but that one didn't mention anything about UTF-8 issues. I'm using Spring Framework 4.1.6, Spring Security 4.0.2 and Spring Webflow 2.4.2.

It revolves around StandardServletMultipartResolver vs. CommonsMultipartResolver as far as I can tell, but I'm not sure. If I use CommonsMultipartResolver I can upload files on any page except for Webflow pages fine and UTF-8 encoding works as well on all pages. However on the Webflow pages an exception is thrown trying to access the file . If I use StandardServletMultipartResolver then all of the file uploads work, including Webflow, but on any page that has a UTF-8 character, e.g., caractère, I get garbage.

The wierd thing is I can see in FireBug that the file is being posted when I use the commons resolver. Also, if I debug the RequestContext coming from Webflow I can also see the file buried 4 levels deep in requests. The code for the common resolver (see end of post for the standard resolver code):

public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
    ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
    MultipartHttpServletRequest multipartRequest = new DefaultMultipartHttpServletRequest((HttpServletRequest)context.getNativeRequest());
    MultipartFile file = multipartRequest.getFile("file");

So, is this a Spring Security issue or a Spring Webflow problem? I suspect the commons resolver would work if I could cast the RequestContext above correctly, but I've tried numerous combinations with no luck. Any guidance on this would be greatly appreciated.

Here are some relevant configurations and code:

WebMvcConfig

@Bean
public CommonsMultipartResolver filterMultipartResolver() {
    CommonsMultipartResolver resolver = new CommonsMultipartResolver();
    resolver.setDefaultEncoding("UTF-8");
    return resolver;
}

SecurityConfig

@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

<action-state id="uploadFile">
    <evaluate expression="fileActions.uploadFile(recipe, flowRequestContext)"/>
    <transition to="review"/>
</action-state>

Upload file method

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

回答1:


Turns out you can cast the RequestContext to get at the underlying MultipartHttpServletRequest but it's not pretty. Here's what I ended up with:

Upload file method

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

Using this I get to keep the CommonsMultipartResolver, all file uploads in the app work whether Webflow or not, and I have no issues with UTF-8 and character mangling.

I'm not particularly happy with this solution (even though it works) since it's dependent upon a specific nesting of requests that could change in the future(?). I'm be interested if anyone else has run into the same UTF-8 issue and how they solved it, but for now I'm going to test the heck out of this and move on.



来源:https://stackoverflow.com/questions/35281868/issue-with-spring-security-spring-webflow-file-uploads-and-utf-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!