mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-31 06:38:42 +00:00 
			
		
		
		
	Merge branch '6.1.x'
This commit is contained in:
		
						commit
						3ab235cd56
					
				| @ -23,12 +23,14 @@ import java.util.LinkedHashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.atomic.AtomicReference; | ||||
| import java.util.function.Supplier; | ||||
| import java.util.function.Function; | ||||
| 
 | ||||
| import jakarta.servlet.DispatcherType; | ||||
| import jakarta.servlet.ServletContext; | ||||
| import jakarta.servlet.ServletRegistration; | ||||
| import jakarta.servlet.http.HttpServletRequest; | ||||
| import org.apache.commons.logging.Log; | ||||
| import org.apache.commons.logging.LogFactory; | ||||
| 
 | ||||
| import org.springframework.beans.factory.NoSuchBeanDefinitionException; | ||||
| import org.springframework.context.ApplicationContext; | ||||
| @ -44,7 +46,6 @@ 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.util.function.SingletonSupplier; | ||||
| import org.springframework.web.context.WebApplicationContext; | ||||
| import org.springframework.web.servlet.handler.HandlerMappingIntrospector; | ||||
| 
 | ||||
| @ -76,6 +77,8 @@ public abstract class AbstractRequestMatcherRegistry<C> { | ||||
| 				AbstractRequestMatcherRegistry.class.getClassLoader()); | ||||
| 	} | ||||
| 
 | ||||
| 	private final Log logger = LogFactory.getLog(getClass()); | ||||
| 
 | ||||
| 	protected final void setApplicationContext(ApplicationContext context) { | ||||
| 		this.context = context; | ||||
| 	} | ||||
| @ -209,7 +212,12 @@ public abstract class AbstractRequestMatcherRegistry<C> { | ||||
| 				matchers.add(resolve(ant, mvc, servletContext)); | ||||
| 			} | ||||
| 			else { | ||||
| 				matchers.add(new DeferredRequestMatcher(() -> resolve(ant, mvc, servletContext), mvc, ant)); | ||||
| 				this.logger | ||||
| 					.warn("The ServletRegistration API was not available at startup time. This may be due to a misconfiguration; " | ||||
| 							+ "if you are using AbstractSecurityWebApplicationInitializer, please double-check the recommendations outlined in " | ||||
| 							+ "https://docs.spring.io/spring-security/reference/servlet/configuration/java.html#abstractsecuritywebapplicationinitializer-with-spring-mvc"); | ||||
| 				matchers.add(new DeferredRequestMatcher((request) -> resolve(ant, mvc, request.getServletContext()), | ||||
| 						mvc, ant)); | ||||
| 			} | ||||
| 		} | ||||
| 		return requestMatchers(matchers.toArray(new RequestMatcher[0])); | ||||
| @ -466,27 +474,34 @@ public abstract class AbstractRequestMatcherRegistry<C> { | ||||
| 
 | ||||
| 	static class DeferredRequestMatcher implements RequestMatcher { | ||||
| 
 | ||||
| 		final Supplier<RequestMatcher> requestMatcher; | ||||
| 		final Function<HttpServletRequest, RequestMatcher> requestMatcherFactory; | ||||
| 
 | ||||
| 		final AtomicReference<String> description = new AtomicReference<>(); | ||||
| 
 | ||||
| 		DeferredRequestMatcher(Supplier<RequestMatcher> resolver, RequestMatcher... candidates) { | ||||
| 			this.requestMatcher = SingletonSupplier.of(() -> { | ||||
| 				RequestMatcher matcher = resolver.get(); | ||||
| 				this.description.set(matcher.toString()); | ||||
| 				return matcher; | ||||
| 			}); | ||||
| 		volatile RequestMatcher requestMatcher; | ||||
| 
 | ||||
| 		DeferredRequestMatcher(Function<HttpServletRequest, RequestMatcher> resolver, RequestMatcher... candidates) { | ||||
| 			this.requestMatcherFactory = (request) -> { | ||||
| 				if (this.requestMatcher == null) { | ||||
| 					synchronized (this) { | ||||
| 						if (this.requestMatcher == null) { | ||||
| 							this.requestMatcher = resolver.apply(request); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				return this.requestMatcher; | ||||
| 			}; | ||||
| 			this.description.set("Deferred " + Arrays.toString(candidates)); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public boolean matches(HttpServletRequest request) { | ||||
| 			return this.requestMatcher.get().matches(request); | ||||
| 			return this.requestMatcherFactory.apply(request).matches(request); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		public MatchResult matcher(HttpServletRequest request) { | ||||
| 			return this.requestMatcher.get().matcher(request); | ||||
| 			return this.requestMatcherFactory.apply(request).matcher(request); | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
|  | ||||
| @ -307,7 +307,7 @@ public class AbstractRequestMatcherRegistryTests { | ||||
| 			List<RequestMatcher> requestMatchers = new ArrayList<>(); | ||||
| 			for (RequestMatcher requestMatcher : wrappedMatchers) { | ||||
| 				if (requestMatcher instanceof AbstractRequestMatcherRegistry.DeferredRequestMatcher) { | ||||
| 					requestMatchers.add(((DeferredRequestMatcher) requestMatcher).requestMatcher.get()); | ||||
| 					requestMatchers.add(((DeferredRequestMatcher) requestMatcher).requestMatcher); | ||||
| 				} | ||||
| 				else { | ||||
| 					requestMatchers.add(requestMatcher); | ||||
|  | ||||
| @ -114,7 +114,7 @@ public class SecurityWebApplicationInitializer | ||||
| 
 | ||||
| This onlys register the `springSecurityFilterChain` for every URL in your application. | ||||
| After that, we need to ensure that `WebSecurityConfig` was loaded in our existing `ApplicationInitializer`. | ||||
| For example, if we use Spring MVC it is added in the `getRootConfigClasses()`: | ||||
| For example, if we use Spring MVC it is added in the `getServletConfigClasses()`: | ||||
| 
 | ||||
| [[message-web-application-inititializer-java]] | ||||
| [source,java] | ||||
| @ -123,14 +123,42 @@ public class MvcWebApplicationInitializer extends | ||||
| 		AbstractAnnotationConfigDispatcherServletInitializer { | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected Class<?>[] getRootConfigClasses() { | ||||
| 		return new Class[] { WebSecurityConfig.class }; | ||||
| 	protected Class<?>[] getServletConfigClasses() { | ||||
| 		return new Class[] { WebSecurityConfig.class, WebMvcConfig.class }; | ||||
| 	} | ||||
| 
 | ||||
| 	// ... other overrides ... | ||||
| } | ||||
| ---- | ||||
| 
 | ||||
| The reason for this is that Spring Security needs to be able to inspect some Spring MVC configuration in order to appropriately configure xref:servlet/authorization/authorize-http-requests.adoc#_request_matchers[underlying request matchers], so they need to be in the same application context. | ||||
| Placing Spring Security in `getRootConfigClasses` places it into a parent application context that may not be able to find Spring MVC's `HandlerMappingIntrospector`. | ||||
| 
 | ||||
| ==== Configuring for Multiple Spring MVC Dispatchers | ||||
| 
 | ||||
| If desired, any Spring Security configuration that is unrelated to Spring MVC may be placed in a different configuration class like so: | ||||
| 
 | ||||
| [source,java] | ||||
| ---- | ||||
| public class MvcWebApplicationInitializer extends | ||||
| 		AbstractAnnotationConfigDispatcherServletInitializer { | ||||
| 
 | ||||
| 	@Override | ||||
|     protected Class<?>[] getRootConfigClasses() { | ||||
| 		return new Class[] { NonWebSecurityConfig.class }; | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected Class<?>[] getServletConfigClasses() { | ||||
| 		return new Class[] { WebSecurityConfig.class, WebMvcConfig.class }; | ||||
| 	} | ||||
| 
 | ||||
| 	// ... other overrides ... | ||||
| } | ||||
| ---- | ||||
| 
 | ||||
| This can be helpful if you have multiple instances of `AbstractAnnotationConfigDispatcherServletInitializer` and don't want to duplicate the general security configuration across both of them. | ||||
| 
 | ||||
| [[jc-httpsecurity]] | ||||
| == HttpSecurity | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user