Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-12114

MockMvc security filters causes FileUploadException: the request was rejected because no multipart boundary was found

    XMLWordPrintable

    Details

      Description

      When testing a controller using MockMvc, file upload works as expected, but when adding the Spring Security filter chain, the request fails with:

      org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
      	at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:163)
      	at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:139)
      	at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1041)
      	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:887)
      	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:851)
      	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
      	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
      	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
      	at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
      	at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:168)
      	at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:136)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
      	at com.unifylog.spring.UserFilter.doFilter(UserFilter.java:30)
      	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
      	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
      	at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:136)
      	at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:141)
      	at com.unifylog.integration.UserIntegrationTest.testUser(UserIntegrationTest.java:124)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
      	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
      	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
      	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
      	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
      	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
      	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
      	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
      	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
      	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
      	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
      	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
      	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
      	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
      	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
      	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
      	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
      	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
      	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
      	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
      	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:48)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
      	at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
      	at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
      	at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
      	at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
      	at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
      	at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
      	at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
      	at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
      	at java.lang.Thread.run(Thread.java:745)
      Caused by: org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
      	at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:990)
      	at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:310)
      	at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:334)
      	at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)
      	at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:156)
      	... 69 more
      

      Even if the filter is a pass through:

      public class UserFilter extends GenericFilterBean {
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              HttpServletRequest httpServletRequest = (HttpServletRequest) request;
              HttpServletResponse httpServletResponse = (HttpServletResponse) response;
              if (validUser(request)) {
                  chain.doFilter(request, response);
              } else {
                  httpServletResponse.setStatus(403);
              }
          }
      }
      

      XML:

      <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
              <sec:filter-chain-map path-type="ant">
                  <sec:filter-chain pattern="/api/**" filters="userFilter"/>
              </sec:filter-chain-map>
          </bean>
      

      What I mean by adding the security filter chain is using this:

      this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilters(this.springSecurityFilterChain).build();
      

      ... instead of just this:

      this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
      

        Attachments

          Activity

            People

            Assignee:
            juergen.hoeller Juergen Hoeller
            Reporter:
            andresesfm Andres A
            Last updater:
            Spring Issues Spring Issues
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Days since last comment:
              3 years, 1 week, 4 days ago