From 86599afd4385854f92b0d5e95049dbf9bd6d9237 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Fri, 21 Mar 2025 12:00:43 -0600 Subject: [PATCH] Rename servletPath to basePath Closes gh-16765 --- .../AuthorizeHttpRequestsConfigurerTests.java | 2 +- .../matcher/PathPatternRequestMatcher.java | 43 +++++++++++-------- .../PathPatternRequestMatcherTests.java | 15 +++---- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurerTests.java index 4d9c39c4b1..057deea40c 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurerTests.java @@ -1364,7 +1364,7 @@ public class AuthorizeHttpRequestsConfigurerTests { @Bean SecurityFilterChain security(HttpSecurity http) throws Exception { - PathPatternRequestMatcher.Builder mvc = PathPatternRequestMatcher.withDefaults().servletPath("/mvc"); + PathPatternRequestMatcher.Builder mvc = PathPatternRequestMatcher.withDefaults().basePath("/mvc"); // @formatter:off http .authorizeHttpRequests((authorize) -> authorize diff --git a/web/src/main/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcher.java b/web/src/main/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcher.java index 6087a8b3fd..c9c92c2b4b 100644 --- a/web/src/main/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcher.java +++ b/web/src/main/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcher.java @@ -166,15 +166,18 @@ public final class PathPatternRequestMatcher implements RequestMatcher { * a {@link PathPatternRequestMatcher}. * *
- * For example, if Spring MVC is deployed to `/mvc` and another servlet to `/other`, - * then you can use this builder to do: - *
+ * To match a request URI like {@code /app/servlet/my/resource/**} where {@code /app} + * is the context path, you can do + * {@code PathPatternRequestMatcher.withDefaults().matcher("/servlet/my/resource/**")} * - *
+ *
+ * If you have many paths that have a common path prefix, you can use
+ * {@link #basePath} to reduce repetition like so:
+ * PathPatternRequestMatcher.Builder mvc = withDefaults().basePath("/mvc");
* http
* .authorizeHttpRequests((authorize) -> authorize
- * .requestMatchers(servletPath("/mvc").matcher("/user/**")).hasAuthority("user")
- * .requestMatchers(servletPath("/other").matcher("/admin/**")).hasAuthority("admin")
+ * .requestMatchers(mvc.matcher("/user/**")).hasAuthority("user")
+ * .requestMatchers(mvc.matcher("/admin/**")).hasAuthority("admin")
* )
* ...
*
@@ -183,7 +186,7 @@ public final class PathPatternRequestMatcher implements RequestMatcher {
private final PathPatternParser parser;
- private final String servletPath;
+ private final String basePath;
Builder() {
this(PathPatternParser.defaultInstance);
@@ -193,22 +196,26 @@ public final class PathPatternRequestMatcher implements RequestMatcher {
this(parser, "");
}
- Builder(PathPatternParser parser, String servletPath) {
+ Builder(PathPatternParser parser, String basePath) {
this.parser = parser;
- this.servletPath = servletPath;
+ this.basePath = basePath;
}
/**
- * Match requests starting with this {@code servletPath}.
- * @param servletPath the servlet path prefix
+ * Match requests starting with this {@code basePath}.
+ *
+ *
+ * Prefixes should be of the form {@code /my/prefix}, starting with a slash, not
+ * ending in a slash, and not containing and wildcards
+ * @param basePath the path prefix
* @return the {@link Builder} for more configuration
*/
- public Builder servletPath(String servletPath) {
- Assert.notNull(servletPath, "servletPath cannot be null");
- Assert.isTrue(servletPath.startsWith("/"), "servletPath must start with '/'");
- Assert.isTrue(!servletPath.endsWith("/"), "servletPath must not end with a slash");
- Assert.isTrue(!servletPath.contains("*"), "servletPath must not contain a star");
- return new Builder(this.parser, servletPath);
+ 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(!basePath.contains("*"), "basePath must not contain a star");
+ return new Builder(this.parser, basePath);
}
/**
@@ -279,7 +286,7 @@ 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.servletPath + path);
+ PathPattern pathPattern = this.parser.parse(this.basePath + path);
PathPatternRequestMatcher requestMatcher = new PathPatternRequestMatcher(pathPattern);
if (method != null) {
requestMatcher.setMethod(new HttpMethodRequestMatcher(method));
diff --git a/web/src/test/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcherTests.java b/web/src/test/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcherTests.java
index cc669f45a8..5040ecb50f 100644
--- a/web/src/test/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcherTests.java
+++ b/web/src/test/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcherTests.java
@@ -87,8 +87,7 @@ public class PathPatternRequestMatcherTests {
@Test
void matcherWhenServletPathThenMatchesOnlyServletPath() {
- PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults()
- .servletPath("/servlet/path");
+ PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults().basePath("/servlet/path");
RequestMatcher matcher = servlet.matcher(HttpMethod.GET, "/endpoint");
ServletContext servletContext = servletContext("/servlet/path");
MockHttpServletRequest mock = get("/servlet/path/endpoint").servletPath("/servlet/path")
@@ -114,8 +113,7 @@ public class PathPatternRequestMatcherTests {
@Test
void matcherWhenMultiServletPathThenMatches() {
- PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults()
- .servletPath("/servlet/path");
+ PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults().basePath("/servlet/path");
RequestMatcher matcher = servlet.matcher(HttpMethod.GET, "/endpoint");
MockHttpServletRequest mock = get("/servlet/path/endpoint").servletPath("/servlet/path").buildRequest(null);
assertThat(matcher.matches(mock)).isTrue();
@@ -123,8 +121,7 @@ public class PathPatternRequestMatcherTests {
@Test
void matcherWhenMultiContextPathThenMatches() {
- PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults()
- .servletPath("/servlet/path");
+ PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults().basePath("/servlet/path");
RequestMatcher matcher = servlet.matcher(HttpMethod.GET, "/endpoint");
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> matcher.matches(
get("/servlet/path/endpoint").servletPath("/servlet/path").contextPath("/app").buildRequest(null)));
@@ -133,11 +130,11 @@ public class PathPatternRequestMatcherTests {
@Test
void servletPathWhenEndsWithSlashOrStarThenIllegalArgument() {
assertThatExceptionOfType(IllegalArgumentException.class)
- .isThrownBy(() -> PathPatternRequestMatcher.withDefaults().servletPath("/path/**"));
+ .isThrownBy(() -> PathPatternRequestMatcher.withDefaults().basePath("/path/**"));
assertThatExceptionOfType(IllegalArgumentException.class)
- .isThrownBy(() -> PathPatternRequestMatcher.withDefaults().servletPath("/path/*"));
+ .isThrownBy(() -> PathPatternRequestMatcher.withDefaults().basePath("/path/*"));
assertThatExceptionOfType(IllegalArgumentException.class)
- .isThrownBy(() -> PathPatternRequestMatcher.withDefaults().servletPath("/path/"));
+ .isThrownBy(() -> PathPatternRequestMatcher.withDefaults().basePath("/path/"));
}
MockHttpServletRequest request(String uri) {