mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	Merge branch '6.2.x' into 6.3.x
Closes gh-15211
This commit is contained in:
		
						commit
						22c7b8760a
					
				| @ -43,11 +43,13 @@ import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.AnyRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.OrRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.RegexRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.RequestMatcher; | ||||
| import org.springframework.util.Assert; | ||||
| import org.springframework.util.ClassUtils; | ||||
| import org.springframework.web.context.WebApplicationContext; | ||||
| import org.springframework.web.servlet.DispatcherServlet; | ||||
| import org.springframework.web.servlet.handler.HandlerMappingIntrospector; | ||||
| 
 | ||||
| /** | ||||
| @ -216,10 +218,10 @@ public abstract class AbstractRequestMatcherRegistry<C> { | ||||
| 	private RequestMatcher resolve(AntPathRequestMatcher ant, MvcRequestMatcher mvc, ServletContext servletContext) { | ||||
| 		Map<String, ? extends ServletRegistration> registrations = mappableServletRegistrations(servletContext); | ||||
| 		if (registrations.isEmpty()) { | ||||
| 			return ant; | ||||
| 			return new DispatcherServletDelegatingRequestMatcher(ant, mvc, new MockMvcRequestMatcher()); | ||||
| 		} | ||||
| 		if (!hasDispatcherServlet(registrations)) { | ||||
| 			return ant; | ||||
| 			return new DispatcherServletDelegatingRequestMatcher(ant, mvc, new MockMvcRequestMatcher()); | ||||
| 		} | ||||
| 		ServletRegistration dispatcherServlet = requireOneRootDispatcherServlet(registrations); | ||||
| 		if (dispatcherServlet != null) { | ||||
| @ -486,18 +488,20 @@ public abstract class AbstractRequestMatcherRegistry<C> { | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	static class DispatcherServletDelegatingRequestMatcher implements RequestMatcher { | ||||
| 	static class MockMvcRequestMatcher implements RequestMatcher { | ||||
| 
 | ||||
| 		private final AntPathRequestMatcher ant; | ||||
| 		@Override | ||||
| 		public boolean matches(HttpServletRequest request) { | ||||
| 			return request.getAttribute("org.springframework.test.web.servlet.MockMvc.MVC_RESULT_ATTRIBUTE") != null; | ||||
| 		} | ||||
| 
 | ||||
| 		private final MvcRequestMatcher mvc; | ||||
| 	} | ||||
| 
 | ||||
| 	static class DispatcherServletRequestMatcher implements RequestMatcher { | ||||
| 
 | ||||
| 		private final ServletContext servletContext; | ||||
| 
 | ||||
| 		DispatcherServletDelegatingRequestMatcher(AntPathRequestMatcher ant, MvcRequestMatcher mvc, | ||||
| 				ServletContext servletContext) { | ||||
| 			this.ant = ant; | ||||
| 			this.mvc = mvc; | ||||
| 		DispatcherServletRequestMatcher(ServletContext servletContext) { | ||||
| 			this.servletContext = servletContext; | ||||
| 		} | ||||
| 
 | ||||
| @ -505,8 +509,49 @@ public abstract class AbstractRequestMatcherRegistry<C> { | ||||
| 		public boolean matches(HttpServletRequest request) { | ||||
| 			String name = request.getHttpServletMapping().getServletName(); | ||||
| 			ServletRegistration registration = this.servletContext.getServletRegistration(name); | ||||
| 			Assert.notNull(registration, "Failed to find servlet [" + name + "] in the servlet context"); | ||||
| 			if (isDispatcherServlet(registration)) { | ||||
| 			Assert.notNull(name, "Failed to find servlet [" + name + "] in the servlet context"); | ||||
| 			try { | ||||
| 				Class<?> clazz = Class.forName(registration.getClassName()); | ||||
| 				return DispatcherServlet.class.isAssignableFrom(clazz); | ||||
| 			} | ||||
| 			catch (ClassNotFoundException ex) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	static class DispatcherServletDelegatingRequestMatcher implements RequestMatcher { | ||||
| 
 | ||||
| 		private final AntPathRequestMatcher ant; | ||||
| 
 | ||||
| 		private final MvcRequestMatcher mvc; | ||||
| 
 | ||||
| 		private final RequestMatcher dispatcherServlet; | ||||
| 
 | ||||
| 		DispatcherServletDelegatingRequestMatcher(AntPathRequestMatcher ant, MvcRequestMatcher mvc, | ||||
| 				ServletContext servletContext) { | ||||
| 			this(ant, mvc, new OrRequestMatcher(new MockMvcRequestMatcher(), | ||||
| 					new DispatcherServletRequestMatcher(servletContext))); | ||||
| 		} | ||||
| 
 | ||||
| 		DispatcherServletDelegatingRequestMatcher(AntPathRequestMatcher ant, MvcRequestMatcher mvc, | ||||
| 				RequestMatcher dispatcherServlet) { | ||||
| 			this.ant = ant; | ||||
| 			this.mvc = mvc; | ||||
| 			this.dispatcherServlet = dispatcherServlet; | ||||
| 		} | ||||
| 
 | ||||
| 		RequestMatcher requestMatcher(HttpServletRequest request) { | ||||
| 			if (this.dispatcherServlet.matches(request)) { | ||||
| 				return this.mvc; | ||||
| 			} | ||||
| 			return this.ant; | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public boolean matches(HttpServletRequest request) { | ||||
| 			if (this.dispatcherServlet.matches(request)) { | ||||
| 				return this.mvc.matches(request); | ||||
| 			} | ||||
| 			return this.ant.matches(request); | ||||
| @ -514,27 +559,12 @@ public abstract class AbstractRequestMatcherRegistry<C> { | ||||
| 
 | ||||
| 		@Override | ||||
| 		public MatchResult matcher(HttpServletRequest request) { | ||||
| 			String name = request.getHttpServletMapping().getServletName(); | ||||
| 			ServletRegistration registration = this.servletContext.getServletRegistration(name); | ||||
| 			Assert.notNull(registration, "Failed to find servlet [" + name + "] in the servlet context"); | ||||
| 			if (isDispatcherServlet(registration)) { | ||||
| 			if (this.dispatcherServlet.matches(request)) { | ||||
| 				return this.mvc.matcher(request); | ||||
| 			} | ||||
| 			return this.ant.matcher(request); | ||||
| 		} | ||||
| 
 | ||||
| 		private boolean isDispatcherServlet(ServletRegistration registration) { | ||||
| 			Class<?> dispatcherServlet = ClassUtils | ||||
| 				.resolveClassName("org.springframework.web.servlet.DispatcherServlet", null); | ||||
| 			try { | ||||
| 				Class<?> clazz = Class.forName(registration.getClassName()); | ||||
| 				return dispatcherServlet.isAssignableFrom(clazz); | ||||
| 			} | ||||
| 			catch (ClassNotFoundException ex) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public String toString() { | ||||
| 			return "DispatcherServletDelegating [" + "ant = " + this.ant + ", mvc = " + this.mvc + "]"; | ||||
|  | ||||
| @ -26,27 +26,35 @@ import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import org.springframework.beans.factory.NoSuchBeanDefinitionException; | ||||
| import org.springframework.context.ApplicationContext; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.http.HttpMethod; | ||||
| import org.springframework.mock.web.MockHttpServletRequest; | ||||
| import org.springframework.security.config.MockServletContext; | ||||
| import org.springframework.security.config.TestMockHttpServletMappings; | ||||
| import org.springframework.security.config.annotation.ObjectPostProcessor; | ||||
| import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.DispatcherServletDelegatingRequestMatcher; | ||||
| import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||||
| import org.springframework.security.config.test.SpringTestContext; | ||||
| import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.RegexRequestMatcher; | ||||
| import org.springframework.security.web.util.matcher.RequestMatcher; | ||||
| import org.springframework.test.web.servlet.MockMvc; | ||||
| import org.springframework.test.web.servlet.setup.MockMvcBuilders; | ||||
| import org.springframework.web.context.WebApplicationContext; | ||||
| import org.springframework.web.servlet.DispatcherServlet; | ||||
| import org.springframework.web.servlet.config.annotation.EnableWebMvc; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||||
| import static org.assertj.core.api.InstanceOfAssertFactories.type; | ||||
| import static org.mockito.BDDMockito.given; | ||||
| import static org.mockito.Mockito.mock; | ||||
| import static org.mockito.Mockito.verify; | ||||
| import static org.mockito.Mockito.verifyNoInteractions; | ||||
| import static org.mockito.Mockito.verifyNoMoreInteractions; | ||||
| import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||||
| 
 | ||||
| /** | ||||
|  * Tests for {@link AbstractRequestMatcherRegistry}. | ||||
| @ -167,18 +175,65 @@ public class AbstractRequestMatcherRegistryTests { | ||||
| 		mockMvcIntrospector(true); | ||||
| 		MockServletContext servletContext = new MockServletContext(); | ||||
| 		given(this.context.getServletContext()).willReturn(servletContext); | ||||
| 		servletContext.addServlet("servletOne", Servlet.class).addMapping("/one"); | ||||
| 		servletContext.addServlet("servletTwo", Servlet.class).addMapping("/two"); | ||||
| 		MockHttpServletRequest request = new MockHttpServletRequest(); | ||||
| 		List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**"); | ||||
| 		assertThat(requestMatchers).isNotEmpty(); | ||||
| 		assertThat(requestMatchers).hasSize(1); | ||||
| 		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class); | ||||
| 		assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class)) | ||||
| 			.extracting((matcher) -> matcher.requestMatcher(request)) | ||||
| 			.isInstanceOf(AntPathRequestMatcher.class); | ||||
| 		servletContext.addServlet("servletOne", Servlet.class).addMapping("/one"); | ||||
| 		servletContext.addServlet("servletTwo", Servlet.class).addMapping("/two"); | ||||
| 		requestMatchers = this.matcherRegistry.requestMatchers("/**"); | ||||
| 		assertThat(requestMatchers).isNotEmpty(); | ||||
| 		assertThat(requestMatchers).hasSize(1); | ||||
| 		assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class)) | ||||
| 			.extracting((matcher) -> matcher.requestMatcher(request)) | ||||
| 			.isInstanceOf(AntPathRequestMatcher.class); | ||||
| 		servletContext.addServlet("servletOne", Servlet.class); | ||||
| 		servletContext.addServlet("servletTwo", Servlet.class); | ||||
| 		requestMatchers = this.matcherRegistry.requestMatchers("/**"); | ||||
| 		assertThat(requestMatchers).isNotEmpty(); | ||||
| 		assertThat(requestMatchers).hasSize(1); | ||||
| 		assertThat(requestMatchers.get(0)).isExactlyInstanceOf(AntPathRequestMatcher.class); | ||||
| 		assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class)) | ||||
| 			.extracting((matcher) -> matcher.requestMatcher(request)) | ||||
| 			.isInstanceOf(AntPathRequestMatcher.class); | ||||
| 	} | ||||
| 
 | ||||
| 	// gh-14418 | ||||
| 	@Test | ||||
| 	public void requestMatchersWhenNoDispatcherServletMockMvcThenMvcRequestMatcherType() throws Exception { | ||||
| 		MockServletContext servletContext = new MockServletContext(); | ||||
| 		try (SpringTestContext spring = new SpringTestContext(this)) { | ||||
| 			spring.register(MockMvcConfiguration.class) | ||||
| 				.postProcessor((context) -> context.setServletContext(servletContext)) | ||||
| 				.autowire(); | ||||
| 			this.matcherRegistry.setApplicationContext(spring.getContext()); | ||||
| 			MockMvc mvc = MockMvcBuilders.webAppContextSetup(spring.getContext()).build(); | ||||
| 			MockHttpServletRequest request = mvc.perform(get("/")).andReturn().getRequest(); | ||||
| 			List<RequestMatcher> requestMatchers = this.matcherRegistry.requestMatchers("/**"); | ||||
| 			assertThat(requestMatchers).isNotEmpty(); | ||||
| 			assertThat(requestMatchers).hasSize(1); | ||||
| 			assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class)) | ||||
| 				.extracting((matcher) -> matcher.requestMatcher(request)) | ||||
| 				.isInstanceOf(MvcRequestMatcher.class); | ||||
| 			servletContext.addServlet("servletOne", Servlet.class).addMapping("/one"); | ||||
| 			servletContext.addServlet("servletTwo", Servlet.class).addMapping("/two"); | ||||
| 			requestMatchers = this.matcherRegistry.requestMatchers("/**"); | ||||
| 			assertThat(requestMatchers).isNotEmpty(); | ||||
| 			assertThat(requestMatchers).hasSize(1); | ||||
| 			assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class)) | ||||
| 				.extracting((matcher) -> matcher.requestMatcher(request)) | ||||
| 				.isInstanceOf(MvcRequestMatcher.class); | ||||
| 			servletContext.addServlet("servletOne", Servlet.class); | ||||
| 			servletContext.addServlet("servletTwo", Servlet.class); | ||||
| 			requestMatchers = this.matcherRegistry.requestMatchers("/**"); | ||||
| 			assertThat(requestMatchers).isNotEmpty(); | ||||
| 			assertThat(requestMatchers).hasSize(1); | ||||
| 			assertThat(requestMatchers.get(0)).asInstanceOf(type(DispatcherServletDelegatingRequestMatcher.class)) | ||||
| 				.extracting((matcher) -> matcher.requestMatcher(request)) | ||||
| 				.isInstanceOf(MvcRequestMatcher.class); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| @ -320,4 +375,11 @@ public class AbstractRequestMatcherRegistryTests { | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	@Configuration | ||||
| 	@EnableWebSecurity | ||||
| 	@EnableWebMvc | ||||
| 	static class MockMvcConfiguration { | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -21,6 +21,7 @@ | ||||
| 		<property name="avoidStaticImportExcludes" value="org.springframework.security.web.util.matcher.AntPathRequestMatcher.*" /> | ||||
| 		<property name="avoidStaticImportExcludes" value="org.springframework.security.web.util.matcher.RegexRequestMatcher.*" /> | ||||
| 		<property name="avoidStaticImportExcludes" value="org.springframework.core.annotation.MergedAnnotations.SearchStrategy.*" /> | ||||
| 		<property name="avoidStaticImportExcludes" value="org.assertj.core.api.InstanceOfAssertFactories.*"/> | ||||
| 	</module> | ||||
| 	<module name="com.puppycrawl.tools.checkstyle.TreeWalker"> | ||||
|  		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck"> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user