소스 검색

Merge remote-tracking branch 'origin/6.5.x'

Josh Cummings 1 주 전
부모
커밋
5da2121e2b

+ 6 - 3
web/src/main/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcher.java

@@ -49,6 +49,7 @@ import org.springframework.web.util.pattern.PathPatternParser;
  * </p>
  *
  * @author Josh Cummings
+ * @author Andrey Litvitski
  * @since 6.5
  */
 public final class PathPatternRequestMatcher implements RequestMatcher {
@@ -234,14 +235,15 @@ public final class PathPatternRequestMatcher implements RequestMatcher {
 		 *
 		 * <p>
 		 * Prefixes should be of the form {@code /my/prefix}, starting with a slash, not
-		 * ending in a slash, and not containing and wildcards
+		 * ending in a slash, and not containing and wildcards The special value
+		 * {@code "/"} may be used to indicate the root context.
 		 * @param basePath the path prefix
 		 * @return the {@link Builder} for more configuration
 		 */
 		public Builder basePath(String basePath) {
 			Assert.notNull(basePath, "basePath cannot be null");
 			Assert.isTrue(basePath.startsWith("/"), "basePath must start with '/'");
-			Assert.isTrue(!basePath.endsWith("/"), "basePath must not end with a slash");
+			Assert.isTrue("/".equals(basePath) || !basePath.endsWith("/"), "basePath must not end with a slash");
 			Assert.isTrue(!basePath.contains("*"), "basePath must not contain a star");
 			return new Builder(this.parser, basePath);
 		}
@@ -316,7 +318,8 @@ public final class PathPatternRequestMatcher implements RequestMatcher {
 		public PathPatternRequestMatcher matcher(@Nullable HttpMethod method, String path) {
 			Assert.notNull(path, "pattern cannot be null");
 			Assert.isTrue(path.startsWith("/"), "pattern must start with a /");
-			PathPattern pathPattern = this.parser.parse(this.basePath + path);
+			String prefix = ("/".equals(this.basePath)) ? "" : this.basePath;
+			PathPattern pathPattern = this.parser.parse(prefix + path);
 			return new PathPatternRequestMatcher(pathPattern,
 					(method != null) ? new HttpMethodRequestMatcher(method) : AnyRequestMatcher.INSTANCE);
 		}

+ 8 - 0
web/src/test/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcherTests.java

@@ -138,6 +138,14 @@ public class PathPatternRequestMatcherTests {
 			.isThrownBy(() -> PathPatternRequestMatcher.withDefaults().basePath("/path/"));
 	}
 
+	@Test
+	void matcherWhenBasePathIsRootThenNoDoubleSlash() {
+		PathPatternRequestMatcher.Builder builder = PathPatternRequestMatcher.withDefaults().basePath("/");
+		RequestMatcher matcher = builder.matcher(HttpMethod.GET, "/path");
+		MockHttpServletRequest mock = get("/path").servletPath("/path").buildRequest(null);
+		assertThat(matcher.matches(mock)).isTrue();
+	}
+
 	MockHttpServletRequest request(String uri) {
 		MockHttpServletRequest request = new MockHttpServletRequest("GET", uri);
 		ServletRequestPathUtils.parseAndCache(request);