mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	Merge branch '6.1.x'
This commit is contained in:
		
						commit
						8f5793afb1
					
				| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2023 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -16,6 +16,7 @@ | ||||
| 
 | ||||
| package org.springframework.security.config.web.server; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.springframework.http.HttpMethod; | ||||
| @ -23,6 +24,8 @@ import org.springframework.security.web.server.util.matcher.OrServerWebExchangeM | ||||
| import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; | ||||
| import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; | ||||
| import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; | ||||
| import org.springframework.web.util.pattern.PathPattern; | ||||
| import org.springframework.web.util.pattern.PathPatternParser; | ||||
| 
 | ||||
| /** | ||||
|  * @author Rob Winch | ||||
| @ -62,7 +65,8 @@ public abstract class AbstractServerWebExchangeMatcherRegistry<T> { | ||||
| 	 * {@link ServerWebExchangeMatcher} | ||||
| 	 */ | ||||
| 	public T pathMatchers(HttpMethod method, String... antPatterns) { | ||||
| 		return matcher(ServerWebExchangeMatchers.pathMatchers(method, antPatterns)); | ||||
| 		List<PathPattern> pathPatterns = parsePatterns(antPatterns); | ||||
| 		return matcher(ServerWebExchangeMatchers.pathMatchers(method, pathPatterns.toArray(new PathPattern[0]))); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| @ -74,7 +78,19 @@ public abstract class AbstractServerWebExchangeMatcherRegistry<T> { | ||||
| 	 * {@link ServerWebExchangeMatcher} | ||||
| 	 */ | ||||
| 	public T pathMatchers(String... antPatterns) { | ||||
| 		return matcher(ServerWebExchangeMatchers.pathMatchers(antPatterns)); | ||||
| 		List<PathPattern> pathPatterns = parsePatterns(antPatterns); | ||||
| 		return matcher(ServerWebExchangeMatchers.pathMatchers(pathPatterns.toArray(new PathPattern[0]))); | ||||
| 	} | ||||
| 
 | ||||
| 	private List<PathPattern> parsePatterns(String[] antPatterns) { | ||||
| 		PathPatternParser parser = getPathPatternParser(); | ||||
| 		List<PathPattern> pathPatterns = new ArrayList<>(antPatterns.length); | ||||
| 		for (String pattern : antPatterns) { | ||||
| 			pattern = parser.initFullPathPattern(pattern); | ||||
| 			PathPattern pathPattern = parser.parse(pattern); | ||||
| 			pathPatterns.add(pathPattern); | ||||
| 		} | ||||
| 		return pathPatterns; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| @ -96,6 +112,10 @@ public abstract class AbstractServerWebExchangeMatcherRegistry<T> { | ||||
| 	 */ | ||||
| 	protected abstract T registerMatcher(ServerWebExchangeMatcher matcher); | ||||
| 
 | ||||
| 	protected PathPatternParser getPathPatternParser() { | ||||
| 		return PathPatternParser.defaultInstance; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Associates a {@link ServerWebExchangeMatcher} instances | ||||
| 	 * @param matcher the {@link ServerWebExchangeMatcher} instance | ||||
|  | ||||
| @ -191,9 +191,11 @@ import org.springframework.web.cors.reactive.CorsConfigurationSource; | ||||
| import org.springframework.web.cors.reactive.CorsProcessor; | ||||
| import org.springframework.web.cors.reactive.CorsWebFilter; | ||||
| import org.springframework.web.cors.reactive.DefaultCorsProcessor; | ||||
| import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; | ||||
| import org.springframework.web.server.ServerWebExchange; | ||||
| import org.springframework.web.server.WebFilter; | ||||
| import org.springframework.web.server.WebFilterChain; | ||||
| import org.springframework.web.util.pattern.PathPatternParser; | ||||
| 
 | ||||
| /** | ||||
|  * A {@link ServerHttpSecurity} is similar to Spring Security's {@code HttpSecurity} but | ||||
| @ -1661,6 +1663,18 @@ public class ServerHttpSecurity { | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	private <T> T getBeanOrNull(String beanName, Class<T> requiredClass) { | ||||
| 		if (this.context == null) { | ||||
| 			return null; | ||||
| 		} | ||||
| 		try { | ||||
| 			return this.context.getBean(beanName, requiredClass); | ||||
| 		} | ||||
| 		catch (Exception ex) { | ||||
| 			return null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private <T> String[] getBeanNamesForTypeOrEmpty(Class<T> beanClass) { | ||||
| 		if (this.context == null) { | ||||
| 			return new String[0]; | ||||
| @ -1681,6 +1695,8 @@ public class ServerHttpSecurity { | ||||
| 	 */ | ||||
| 	public class AuthorizeExchangeSpec extends AbstractServerWebExchangeMatcherRegistry<AuthorizeExchangeSpec.Access> { | ||||
| 
 | ||||
| 		private static final String REQUEST_MAPPING_HANDLER_MAPPING_BEAN_NAME = "requestMappingHandlerMapping"; | ||||
| 
 | ||||
| 		private DelegatingReactiveAuthorizationManager.Builder managerBldr = DelegatingReactiveAuthorizationManager | ||||
| 				.builder(); | ||||
| 
 | ||||
| @ -1688,6 +1704,8 @@ public class ServerHttpSecurity { | ||||
| 
 | ||||
| 		private boolean anyExchangeRegistered; | ||||
| 
 | ||||
| 		private PathPatternParser pathPatternParser; | ||||
| 
 | ||||
| 		/** | ||||
| 		 * Allows method chaining to continue configuring the {@link ServerHttpSecurity} | ||||
| 		 * @return the {@link ServerHttpSecurity} to continue configuring | ||||
| @ -1710,6 +1728,22 @@ public class ServerHttpSecurity { | ||||
| 			return result; | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		protected PathPatternParser getPathPatternParser() { | ||||
| 			if (this.pathPatternParser != null) { | ||||
| 				return this.pathPatternParser; | ||||
| 			} | ||||
| 			RequestMappingHandlerMapping requestMappingHandlerMapping = getBeanOrNull( | ||||
| 					REQUEST_MAPPING_HANDLER_MAPPING_BEAN_NAME, RequestMappingHandlerMapping.class); | ||||
| 			if (requestMappingHandlerMapping != null) { | ||||
| 				this.pathPatternParser = requestMappingHandlerMapping.getPathPatternParser(); | ||||
| 			} | ||||
| 			if (this.pathPatternParser == null) { | ||||
| 				this.pathPatternParser = PathPatternParser.defaultInstance; | ||||
| 			} | ||||
| 			return this.pathPatternParser; | ||||
| 		} | ||||
| 
 | ||||
| 		@Override | ||||
| 		protected Access registerMatcher(ServerWebExchangeMatcher matcher) { | ||||
| 			Assert.state(!this.anyExchangeRegistered, () -> "Cannot register " + matcher | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2020 the original author or authors. | ||||
|  * Copyright 2002-2023 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -42,8 +42,6 @@ public final class PathPatternParserServerWebExchangeMatcher implements ServerWe | ||||
| 
 | ||||
| 	private static final Log logger = LogFactory.getLog(PathPatternParserServerWebExchangeMatcher.class); | ||||
| 
 | ||||
| 	private static final PathPatternParser DEFAULT_PATTERN_PARSER = new PathPatternParser(); | ||||
| 
 | ||||
| 	private final PathPattern pattern; | ||||
| 
 | ||||
| 	private final HttpMethod method; | ||||
| @ -60,7 +58,7 @@ public final class PathPatternParserServerWebExchangeMatcher implements ServerWe | ||||
| 
 | ||||
| 	public PathPatternParserServerWebExchangeMatcher(String pattern, HttpMethod method) { | ||||
| 		Assert.notNull(pattern, "pattern cannot be null"); | ||||
| 		this.pattern = DEFAULT_PATTERN_PARSER.parse(pattern); | ||||
| 		this.pattern = parse(pattern); | ||||
| 		this.method = method; | ||||
| 	} | ||||
| 
 | ||||
| @ -68,6 +66,12 @@ public final class PathPatternParserServerWebExchangeMatcher implements ServerWe | ||||
| 		this(pattern, null); | ||||
| 	} | ||||
| 
 | ||||
| 	private PathPattern parse(String pattern) { | ||||
| 		PathPatternParser parser = PathPatternParser.defaultInstance; | ||||
| 		pattern = parser.initFullPathPattern(pattern); | ||||
| 		return parser.parse(pattern); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public Mono<MatchResult> matches(ServerWebExchange exchange) { | ||||
| 		ServerHttpRequest request = exchange.getRequest(); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2017 the original author or authors. | ||||
|  * Copyright 2002-2023 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -23,6 +23,7 @@ import reactor.core.publisher.Mono; | ||||
| 
 | ||||
| import org.springframework.http.HttpMethod; | ||||
| import org.springframework.web.server.ServerWebExchange; | ||||
| import org.springframework.web.util.pattern.PathPattern; | ||||
| 
 | ||||
| /** | ||||
|  * Provides factory methods for creating common {@link ServerWebExchangeMatcher} | ||||
| @ -59,6 +60,30 @@ public abstract class ServerWebExchangeMatchers { | ||||
| 		return pathMatchers(null, patterns); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Creates a matcher that matches on any of the provided {@link PathPattern}s. | ||||
| 	 * @param pathPatterns the {@link PathPattern}s to match on | ||||
| 	 * @return the matcher to use | ||||
| 	 */ | ||||
| 	public static ServerWebExchangeMatcher pathMatchers(PathPattern... pathPatterns) { | ||||
| 		return pathMatchers(null, pathPatterns); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Creates a matcher that matches on the specific method and any of the provided | ||||
| 	 * {@link PathPattern}s. | ||||
| 	 * @param method the method to match on. If null, any method will be matched. | ||||
| 	 * @param pathPatterns the {@link PathPattern}s to match on | ||||
| 	 * @return the matcher to use | ||||
| 	 */ | ||||
| 	public static ServerWebExchangeMatcher pathMatchers(HttpMethod method, PathPattern... pathPatterns) { | ||||
| 		List<ServerWebExchangeMatcher> matchers = new ArrayList<>(pathPatterns.length); | ||||
| 		for (PathPattern pathPattern : pathPatterns) { | ||||
| 			matchers.add(new PathPatternParserServerWebExchangeMatcher(pathPattern, method)); | ||||
| 		} | ||||
| 		return new OrServerWebExchangeMatcher(matchers); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Creates a matcher that will match on any of the provided matchers | ||||
| 	 * @param matchers the matchers to match on | ||||
|  | ||||
| @ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * Copyright 2002-2023 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      https://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package org.springframework.security.web.server.util.matcher; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import org.springframework.mock.http.server.reactive.MockServerHttpRequest; | ||||
| import org.springframework.mock.web.server.MockServerWebExchange; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| 
 | ||||
| /** | ||||
|  * Tests for {@link PathPatternParserServerWebExchangeMatcher} | ||||
|  * | ||||
|  * @author Marcus da Coregio | ||||
|  */ | ||||
| class PathPatternParserServerWebExchangeMatcherTests { | ||||
| 
 | ||||
| 	@Test | ||||
| 	void matchesWhenConfiguredWithNoTrailingSlashAndPathContainsSlashThenMatches() { | ||||
| 		PathPatternParserServerWebExchangeMatcher matcher = new PathPatternParserServerWebExchangeMatcher("user/**"); | ||||
| 		MockServerHttpRequest request = MockServerHttpRequest.get("/user/test").build(); | ||||
| 		assertThat(matcher.matches(MockServerWebExchange.from(request)).block().isMatch()).isTrue(); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user