Spring Security & Multipart 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15058548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:45:16  来源:igfitidea点击:

Spring Security & Multipart requests

springfile-uploadspring-securityoauth-2.0

提问by Matthew Runo

I have a @Controller protected with Spring Security and OAuth2 in which I am trying to let my users upload a file:

我有一个受 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());
    }
}

When I try to upload a file and title, I get the following exception. I am setting the Content-Type header to multipart/form-data.

当我尝试上传文件和标题时,出现以下异常。我将 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)

How can I do file uploads behind Spring Security? It seems like the request never gets turned into a MultiPartHttpServerRequest and so it doesn't work?

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

If I change my method signature to take a @RequestParam MultipartFile, then I get an exception like:

如果我将方法签名更改为采用 @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)

...but I do have a MultipartResolver configured in my XML:

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

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="268435456"/> <!-- 256 megs -->
</bean>

I did see this blog post about getting this working under Spring 3.0- but I'm trying to stay more up to date and am using 3.1 currently. Is there perhaps an updated fix?

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

回答by Matthew Runo

The problem is that I'm using a PUT instead of a POST. Commons FileUpload is hard coded to only accept POST requests for files.

问题是我使用的是 PUT 而不是 POST。Commons FileUpload 是硬编码的,只接受文件的 POST 请求。

Check the isMultipartContent methodthere. To fix this, either use a POST or extend that class and override that method to work how you like.

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

I opened FILEUPLOAD-214for this issue.

我为此问题打开了FILEUPLOAD-214

回答by steve chen

To solve the problem, do not use spring MultiPartHttpServerRequest, instead taking the request as HttpServletRequest, using the apache commons fileupload library to parse the request from PUT method, and processing the file. Here are some sample code:

解决问题,不使用spring MultiPartHttpServerRequest,而是将请求作为HttpServletRequest,使用apache commons fileupload库解析PUT方法的请求,并处理文件。下面是一些示例代码:

ServletFileUpload fileUpload = new ServletFileUpload(new DiskFileItemFactory());
List<FileItem> fileItems = fileUpload.parseRequest(httpServletRequest);
InputStream in = fileItems.get(0).getInputStream();
...

回答by Nazeel

In Config.groovy

在 Config.groovy 中

Make sure multipart is enabled,

确保启用多部分,

// whether to disable processing of multi part requests
   grails.web.disable.multipart=false

In controller add Post method

在控制器中添加 Post 方法

def upload(){
    MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
    if(request instanceof MultipartHttpServletRequest)
            {
                CommonsMultipartFile f = (CommonsMultipartFile) mpr.getFile("myFile");
                println f.contentType
                f.transferTo()
                if(!f.empty)
                    flash.message = 'success'
                else
                    flash.message = 'file cannot be empty'
            }
    else
    flash.message = 'request is not of type MultipartHttpServletRequest'}

with these, I was able upload the file, nothing related Spring Security.

有了这些,我就可以上传文件,与 Spring Security 无关。

回答by Josh Long

you might take a look at https://github.com/joshlong/the-spring-tutorialwhich has an example demonstrating how to post to Spring MVC with Spring Security OAuth enabled. I even use HTML5 drag and drop to drag the image onto the screen then submit it via ajax to the server.

您可以查看https://github.com/joshlong/the-spring-tutorial,其中有一个示例演示如何在启用 Spring Security OAuth 的情况下发布到 Spring MVC。我什至使用 HTML5 拖放将图像拖到屏幕上,然后通过 ajax 将其提交到服务器。