浏览代码

RequestCache ignores multipart requests

Fixes gh-7060
Rob Winch 6 年之前
父节点
当前提交
71444ff5dc

+ 14 - 12
config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java

@@ -142,22 +142,12 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>> exte
 			return null;
 		}
 	}
+
 	@SuppressWarnings("unchecked")
 	private RequestMatcher createDefaultSavedRequestMatcher(H http) {
-		ContentNegotiationStrategy contentNegotiationStrategy = http
-				.getSharedObject(ContentNegotiationStrategy.class);
-		if (contentNegotiationStrategy == null) {
-			contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
-		}
-
 		RequestMatcher notFavIcon = new NegatedRequestMatcher(new AntPathRequestMatcher(
 				"/**/favicon.*"));
 
-		MediaTypeRequestMatcher jsonRequest = new MediaTypeRequestMatcher(
-				contentNegotiationStrategy, MediaType.APPLICATION_JSON);
-		jsonRequest.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
-		RequestMatcher notJson = new NegatedRequestMatcher(jsonRequest);
-
 		RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
 				new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
 
@@ -169,9 +159,21 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>> exte
 			matchers.add(0, getRequests);
 		}
 		matchers.add(notFavIcon);
-		matchers.add(notJson);
+		matchers.add(notMatchingMediaType(http, MediaType.APPLICATION_JSON));
 		matchers.add(notXRequestedWith);
+		matchers.add(notMatchingMediaType(http, MediaType.MULTIPART_FORM_DATA));
 
 		return new AndRequestMatcher(matchers);
 	}
+
+	private RequestMatcher notMatchingMediaType(H http, MediaType mediaType) {
+		ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);
+		if (contentNegotiationStrategy == null) {
+			contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
+		}
+
+		MediaTypeRequestMatcher mediaRequest = new MediaTypeRequestMatcher(contentNegotiationStrategy, mediaType);
+		mediaRequest.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
+		return new NegatedRequestMatcher(mediaRequest);
+	}
 }

+ 17 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurerTests.java

@@ -26,6 +26,7 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.mock.web.MockHttpSession;
+import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.security.config.annotation.ObjectPostProcessor;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@@ -47,6 +48,7 @@ import static org.springframework.security.config.Customizer.withDefaults;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
 
 /**
@@ -264,6 +266,21 @@ public class RequestCacheConfigurerTests {
 				.andExpect(redirectedUrl("/"));
 	}
 
+	// SEC-7060
+	@Test
+	public void postWhenRequestIsMultipartThenPostAuthenticationRedirectsToRoot() throws Exception {
+		this.spring.register(RequestCacheDefaultsConfig.class, DefaultSecurityConfig.class).autowire();
+
+		MockMultipartFile aFile = new MockMultipartFile("aFile", "A_FILE".getBytes());
+
+		MockHttpSession session = (MockHttpSession)
+				this.mvc.perform(multipart("/upload")
+						.file(aFile))
+						.andReturn().getRequest().getSession();
+
+		this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/"));
+	}
+
 	@EnableWebSecurity
 	static class RequestCacheDisabledConfig extends WebSecurityConfigurerAdapter {
 		@Override