Skip to content

Commit 86599af

Browse files
committed
Rename servletPath to basePath
Closes gh-16765
1 parent c53bf2b commit 86599af

File tree

3 files changed

+32
-28
lines changed

3 files changed

+32
-28
lines changed

config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurerTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,7 @@ static class MvcRequestMatcherBuilderConfig {
13641364

13651365
@Bean
13661366
SecurityFilterChain security(HttpSecurity http) throws Exception {
1367-
PathPatternRequestMatcher.Builder mvc = PathPatternRequestMatcher.withDefaults().servletPath("/mvc");
1367+
PathPatternRequestMatcher.Builder mvc = PathPatternRequestMatcher.withDefaults().basePath("/mvc");
13681368
// @formatter:off
13691369
http
13701370
.authorizeHttpRequests((authorize) -> authorize

web/src/main/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcher.java

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,18 @@ public String toString() {
166166
* a {@link PathPatternRequestMatcher}.
167167
*
168168
* <p>
169-
* For example, if Spring MVC is deployed to `/mvc` and another servlet to `/other`,
170-
* then you can use this builder to do:
171-
* </p>
169+
* To match a request URI like {@code /app/servlet/my/resource/**} where {@code /app}
170+
* is the context path, you can do
171+
* {@code PathPatternRequestMatcher.withDefaults().matcher("/servlet/my/resource/**")}
172172
*
173-
* <code>
173+
* <p>
174+
* If you have many paths that have a common path prefix, you can use
175+
* {@link #basePath} to reduce repetition like so: <code>
176+
* PathPatternRequestMatcher.Builder mvc = withDefaults().basePath("/mvc");
174177
* http
175178
* .authorizeHttpRequests((authorize) -> authorize
176-
* .requestMatchers(servletPath("/mvc").matcher("/user/**")).hasAuthority("user")
177-
* .requestMatchers(servletPath("/other").matcher("/admin/**")).hasAuthority("admin")
179+
* .requestMatchers(mvc.matcher("/user/**")).hasAuthority("user")
180+
* .requestMatchers(mvc.matcher("/admin/**")).hasAuthority("admin")
178181
* )
179182
* ...
180183
* </code>
@@ -183,7 +186,7 @@ public static final class Builder {
183186

184187
private final PathPatternParser parser;
185188

186-
private final String servletPath;
189+
private final String basePath;
187190

188191
Builder() {
189192
this(PathPatternParser.defaultInstance);
@@ -193,22 +196,26 @@ public static final class Builder {
193196
this(parser, "");
194197
}
195198

196-
Builder(PathPatternParser parser, String servletPath) {
199+
Builder(PathPatternParser parser, String basePath) {
197200
this.parser = parser;
198-
this.servletPath = servletPath;
201+
this.basePath = basePath;
199202
}
200203

201204
/**
202-
* Match requests starting with this {@code servletPath}.
203-
* @param servletPath the servlet path prefix
205+
* Match requests starting with this {@code basePath}.
206+
*
207+
* <p>
208+
* Prefixes should be of the form {@code /my/prefix}, starting with a slash, not
209+
* ending in a slash, and not containing and wildcards
210+
* @param basePath the path prefix
204211
* @return the {@link Builder} for more configuration
205212
*/
206-
public Builder servletPath(String servletPath) {
207-
Assert.notNull(servletPath, "servletPath cannot be null");
208-
Assert.isTrue(servletPath.startsWith("/"), "servletPath must start with '/'");
209-
Assert.isTrue(!servletPath.endsWith("/"), "servletPath must not end with a slash");
210-
Assert.isTrue(!servletPath.contains("*"), "servletPath must not contain a star");
211-
return new Builder(this.parser, servletPath);
213+
public Builder basePath(String basePath) {
214+
Assert.notNull(basePath, "basePath cannot be null");
215+
Assert.isTrue(basePath.startsWith("/"), "basePath must start with '/'");
216+
Assert.isTrue(!basePath.endsWith("/"), "basePath must not end with a slash");
217+
Assert.isTrue(!basePath.contains("*"), "basePath must not contain a star");
218+
return new Builder(this.parser, basePath);
212219
}
213220

214221
/**
@@ -279,7 +286,7 @@ public PathPatternRequestMatcher matcher(String path) {
279286
public PathPatternRequestMatcher matcher(@Nullable HttpMethod method, String path) {
280287
Assert.notNull(path, "pattern cannot be null");
281288
Assert.isTrue(path.startsWith("/"), "pattern must start with a /");
282-
PathPattern pathPattern = this.parser.parse(this.servletPath + path);
289+
PathPattern pathPattern = this.parser.parse(this.basePath + path);
283290
PathPatternRequestMatcher requestMatcher = new PathPatternRequestMatcher(pathPattern);
284291
if (method != null) {
285292
requestMatcher.setMethod(new HttpMethodRequestMatcher(method));

web/src/test/java/org/springframework/security/web/servlet/util/matcher/PathPatternRequestMatcherTests.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ void matcherWhenNoMethodThenMatches() {
8787

8888
@Test
8989
void matcherWhenServletPathThenMatchesOnlyServletPath() {
90-
PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults()
91-
.servletPath("/servlet/path");
90+
PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults().basePath("/servlet/path");
9291
RequestMatcher matcher = servlet.matcher(HttpMethod.GET, "/endpoint");
9392
ServletContext servletContext = servletContext("/servlet/path");
9493
MockHttpServletRequest mock = get("/servlet/path/endpoint").servletPath("/servlet/path")
@@ -114,17 +113,15 @@ void matcherWhenRequestPathThenRequiresServletPath() {
114113

115114
@Test
116115
void matcherWhenMultiServletPathThenMatches() {
117-
PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults()
118-
.servletPath("/servlet/path");
116+
PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults().basePath("/servlet/path");
119117
RequestMatcher matcher = servlet.matcher(HttpMethod.GET, "/endpoint");
120118
MockHttpServletRequest mock = get("/servlet/path/endpoint").servletPath("/servlet/path").buildRequest(null);
121119
assertThat(matcher.matches(mock)).isTrue();
122120
}
123121

124122
@Test
125123
void matcherWhenMultiContextPathThenMatches() {
126-
PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults()
127-
.servletPath("/servlet/path");
124+
PathPatternRequestMatcher.Builder servlet = PathPatternRequestMatcher.withDefaults().basePath("/servlet/path");
128125
RequestMatcher matcher = servlet.matcher(HttpMethod.GET, "/endpoint");
129126
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> matcher.matches(
130127
get("/servlet/path/endpoint").servletPath("/servlet/path").contextPath("/app").buildRequest(null)));
@@ -133,11 +130,11 @@ void matcherWhenMultiContextPathThenMatches() {
133130
@Test
134131
void servletPathWhenEndsWithSlashOrStarThenIllegalArgument() {
135132
assertThatExceptionOfType(IllegalArgumentException.class)
136-
.isThrownBy(() -> PathPatternRequestMatcher.withDefaults().servletPath("/path/**"));
133+
.isThrownBy(() -> PathPatternRequestMatcher.withDefaults().basePath("/path/**"));
137134
assertThatExceptionOfType(IllegalArgumentException.class)
138-
.isThrownBy(() -> PathPatternRequestMatcher.withDefaults().servletPath("/path/*"));
135+
.isThrownBy(() -> PathPatternRequestMatcher.withDefaults().basePath("/path/*"));
139136
assertThatExceptionOfType(IllegalArgumentException.class)
140-
.isThrownBy(() -> PathPatternRequestMatcher.withDefaults().servletPath("/path/"));
137+
.isThrownBy(() -> PathPatternRequestMatcher.withDefaults().basePath("/path/"));
141138
}
142139

143140
MockHttpServletRequest request(String uri) {

0 commit comments

Comments
 (0)