Spring Security和Multipart请求

Mat*_*uno 23 spring file-upload spring-security oauth-2.0

我有一个受Spring Security和OAuth2保护的@Controller,我试图让我的用户上传一个文件:

@Controller
@RequestMapping(value = "/api/image")
public class ImageController {

    @PreAuthorize("hasAuthority('ROLE_USER')")
    @RequestMapping(value = "/upload", method = RequestMethod.PUT)
    public @ResponseBody Account putImage(@RequestParam("title") String title, MultipartHttpServletRequest request, Principal principal){
        // Some type of file processing...
        System.out.println("-------------------------------------------");
        System.out.println("Test upload: " + title);
        System.out.println("Test upload: " + request.getFile("file").getOriginalFilename());
        System.out.println("-------------------------------------------");

        return ((Account) ((OAuth2Authentication) principal).getPrincipal());
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试上传文件和标题时,我得到以下异常.我将Content-Type标头设置为multipart/form-data.

java.lang.IllegalStateException: Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]: SecurityContextHolderAwareRequestWrapper[ FirewalledRequest[ org.apache.catalina.connector.RequestFacade@1aee75b7]]
    at org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver.resolveArgument(ServletRequestMethodArgumentResolver.java:84)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
Run Code Online (Sandbox Code Playgroud)

如何在Spring Security后面上传文件?似乎请求永远不会变成MultiPartHttpServerRequest,所以它不起作用?

如果我更改我的方法签名以获取@RequestParam MultipartFile,那么我会得到一个例外:

DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean 'imageController'
DEBUG ExceptionHandlerExceptionResolver - Resolving exception from handler [public com.tinsel.server.model.Account com.tinsel.server.controller.ImageController.putImage(java.lang.String,org.springframework.web.multipart.MultipartFile,java.security.Principal)]: java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
DEBUG ResponseStatusExceptionResolver - Resolving exception from handler [public com.tinsel.server.model.Account com.tinsel.server.controller.ImageController.putImage(java.lang.String,org.springframework.web.multipart.MultipartFile,java.security.Principal)]: java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
DEBUG DefaultHandlerExceptionResolver - Resolving exception from handler [public com.tinsel.server.model.Account com.tinsel.server.controller.ImageController.putImage(java.lang.String,org.springframework.web.multipart.MultipartFile,java.security.Principal)]: java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
DEBUG DispatcherServlet - Could not complete request
java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
    at org.springframework.util.Assert.notNull(Assert.java:112)
Run Code Online (Sandbox Code Playgroud)

...但我确实在我的XML中配置了MultipartResolver:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="268435456"/> <!-- 256 megs -->
</bean>
Run Code Online (Sandbox Code Playgroud)

我确实看到这篇关于让它在Spring 3.0下工作的博客文章 - 但我正在努力保持更新,目前正在使用3.1.是否有更新的修复程序?

Mat*_*uno 25

问题是我使用的是PUT而不是POST.Commons FileUpload被硬编码为仅接受文件的POST请求.

检查那里的isMultipartContent方法.要解决此问题,请使用POST或扩展该类,并覆盖该方法以按您喜欢的方式工作.

我为这个问题打开了FILEUPLOAD-214.

  • FILEUPLOAD-214用WONTFIX解决了.根据作者的说法,"PUT"不应该与`Multipart`一起使用 (4认同)
  • 在1.3.1中经过3年它仍然存在 - [只有POST](http://grepcode.com/file/repo1.maven.org/maven2/commons-fileupload/commons-fileupload/1.3.1/org/apache/公共/文件上传/ servlet的/ ServletFileUpload.java?AV = F). (2认同)