Skip to content

Commit 308de07

Browse files
committed
Always match the links endpoint with GET
The links endpoint only supports GET, so its matcher is now hardcoded to GET. withHttpMethod(...) continues to apply only to endpoint paths and the behaviour is documented on its Javadoc. Signed-off-by: Lee JiWon <dlwldnjs1009@gmail.com>
1 parent 24f6214 commit 308de07

4 files changed

Lines changed: 48 additions & 33 deletions

File tree

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public static EndpointServerWebExchangeMatcher to(String... endpoints) {
119119
* @return the configured {@link ServerWebExchangeMatcher}
120120
*/
121121
public static LinksServerWebExchangeMatcher toLinks() {
122-
return new LinksServerWebExchangeMatcher(null);
122+
return new LinksServerWebExchangeMatcher();
123123
}
124124

125125
/**
@@ -316,6 +316,8 @@ public EndpointServerWebExchangeMatcher excludingLinks() {
316316

317317
/**
318318
* Restricts the matcher to only consider requests with a particular http method.
319+
* <p>
320+
* The links endpoint, if included, is always matched using {@code GET}.
319321
* @param httpMethod the http method to include
320322
* @return a copy of the matcher further restricted to only match requests with
321323
* the specified http method
@@ -335,7 +337,7 @@ protected ServerWebExchangeMatcher createDelegate(PathMappedEndpoints endpoints)
335337
List<ServerWebExchangeMatcher> delegateMatchers = getDelegateMatchers(paths, this.httpMethod);
336338
String linksPath = getLinksPath(endpoints.getBasePath());
337339
if (this.includeLinks && linksPath != null) {
338-
delegateMatchers.add(new LinksServerWebExchangeMatcher(this.httpMethod));
340+
delegateMatchers.add(new LinksServerWebExchangeMatcher());
339341
}
340342
if (delegateMatchers.isEmpty()) {
341343
return EMPTY_MATCHER;
@@ -364,21 +366,18 @@ public String toString() {
364366
*/
365367
public static final class LinksServerWebExchangeMatcher extends AbstractWebExchangeMatcher<WebEndpointProperties> {
366368

367-
private final HttpMethod httpMethod;
368-
369-
private LinksServerWebExchangeMatcher(HttpMethod httpMethod) {
369+
private LinksServerWebExchangeMatcher() {
370370
super(WebEndpointProperties.class);
371-
this.httpMethod = httpMethod;
372371
}
373372

374373
@Override
375374
protected ServerWebExchangeMatcher createDelegate(WebEndpointProperties properties) {
376375
String linksPath = getLinksPath(properties.getBasePath());
377376
if (linksPath != null) {
378377
List<ServerWebExchangeMatcher> linksMatchers = new ArrayList<>();
379-
linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath, this.httpMethod));
378+
linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath, HttpMethod.GET));
380379
if (!linksPath.endsWith("/")) {
381-
linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath + "/", this.httpMethod));
380+
linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath + "/", HttpMethod.GET));
382381
}
383382
return new OrServerWebExchangeMatcher(linksMatchers);
384383
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,11 @@ protected final List<RequestMatcher> getDelegateMatchers(RequestMatcherFactory r
225225
}
226226

227227
protected List<RequestMatcher> getLinksMatchers(RequestMatcherFactory requestMatcherFactory,
228-
RequestMatcherProvider matcherProvider, HttpMethod httpMethod, String linksPath) {
228+
RequestMatcherProvider matcherProvider, String linksPath) {
229229
List<RequestMatcher> linksMatchers = new ArrayList<>();
230-
linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, httpMethod, linksPath));
230+
linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, HttpMethod.GET, linksPath));
231231
if (!linksPath.endsWith("/")) {
232-
linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, httpMethod, linksPath, "/"));
232+
linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, HttpMethod.GET, linksPath, "/"));
233233
}
234234
return linksMatchers;
235235
}
@@ -350,6 +350,8 @@ public EndpointRequestMatcher excludingLinks() {
350350

351351
/**
352352
* Restricts the matcher to only consider requests with a particular HTTP method.
353+
* <p>
354+
* The links endpoint, if included, is always matched using {@code GET}.
353355
* @param httpMethod the HTTP method to include
354356
* @return a copy of the matcher further restricted to only match requests with
355357
* the specified HTTP method
@@ -375,8 +377,7 @@ protected RequestMatcher createDelegate(WebApplicationContext context,
375377
String basePath = endpoints.getBasePath();
376378
String linksPath = getLinksPath(context, basePath);
377379
if (this.includeLinks && linksPath != null) {
378-
delegateMatchers
379-
.addAll(getLinksMatchers(requestMatcherFactory, matcherProvider, this.httpMethod, linksPath));
380+
delegateMatchers.addAll(getLinksMatchers(requestMatcherFactory, matcherProvider, linksPath));
380381
}
381382
if (delegateMatchers.isEmpty()) {
382383
return EMPTY_MATCHER;
@@ -412,7 +413,7 @@ protected RequestMatcher createDelegate(WebApplicationContext context,
412413
String linksPath = getLinksPath(context, properties.getBasePath());
413414
if (linksPath != null) {
414415
return new OrRequestMatcher(
415-
getLinksMatchers(requestMatcherFactory, getRequestMatcherProvider(context), null, linksPath));
416+
getLinksMatchers(requestMatcherFactory, getRequestMatcherProvider(context), linksPath));
416417
}
417418
return EMPTY_MATCHER;
418419
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestTests.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,15 @@ void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() {
7373
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().withHttpMethod(HttpMethod.POST);
7474
assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/foo");
7575
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo");
76-
assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator");
77-
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator");
78-
assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/");
79-
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/");
76+
}
77+
78+
@Test
79+
void toAnyEndpointWithHttpMethodShouldUseGetForLinks() {
80+
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().withHttpMethod(HttpMethod.POST);
81+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator");
82+
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.POST, "/actuator");
83+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator/");
84+
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.POST, "/actuator/");
8085
}
8186

8287
@Test
@@ -144,8 +149,10 @@ void toLinksShouldOnlyMatchLinks() {
144149
ServerWebExchangeMatcher matcher = EndpointRequest.toLinks();
145150
assertMatcher(matcher).doesNotMatch("/actuator/foo");
146151
assertMatcher(matcher).doesNotMatch("/actuator/bar");
147-
assertMatcher(matcher).matches("/actuator");
148-
assertMatcher(matcher).matches("/actuator/");
152+
assertMatcher(matcher).matches(HttpMethod.GET, "/actuator");
153+
assertMatcher(matcher).doesNotMatch(HttpMethod.POST, "/actuator");
154+
assertMatcher(matcher).matches(HttpMethod.GET, "/actuator/");
155+
assertMatcher(matcher).doesNotMatch(HttpMethod.POST, "/actuator/");
149156
}
150157

151158
@Test

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ void toAnyEndpointShouldMatchEndpointPath() {
6464
assertMatcher(matcher, "/actuator").matches("/actuator/foo/zoo/");
6565
assertMatcher(matcher, "/actuator").matches("/actuator/bar");
6666
assertMatcher(matcher, "/actuator").matches("/actuator/bar/baz");
67-
assertMatcher(matcher, "/actuator").matches("/actuator");
67+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator");
6868
}
6969

7070
@Test
@@ -73,18 +73,24 @@ void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() {
7373
.withHttpMethod(HttpMethod.POST);
7474
assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/foo");
7575
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo");
76-
assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator");
77-
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator");
78-
assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/");
79-
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/");
76+
}
77+
78+
@Test
79+
void toAnyEndpointWithHttpMethodShouldUseGetForLinks() {
80+
EndpointRequest.EndpointRequestMatcher matcher = EndpointRequest.toAnyEndpoint()
81+
.withHttpMethod(HttpMethod.POST);
82+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator");
83+
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.POST, "/actuator");
84+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator/");
85+
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.POST, "/actuator/");
8086
}
8187

8288
@Test
8389
void toAnyEndpointShouldMatchEndpointPathWithTrailingSlash() {
8490
RequestMatcher matcher = EndpointRequest.toAnyEndpoint();
8591
assertMatcher(matcher, "/actuator").matches("/actuator/foo/");
8692
assertMatcher(matcher, "/actuator").matches("/actuator/bar/");
87-
assertMatcher(matcher, "/actuator").matches("/actuator/");
93+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator/");
8894
}
8995

9096
@Test
@@ -101,7 +107,7 @@ void toAnyEndpointWhenBasePathIsEmptyAndManagementPortDifferentShouldMatchLinks(
101107
RequestMatcher matcher = EndpointRequest.toAnyEndpoint();
102108
RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), null,
103109
WebServerNamespace.MANAGEMENT);
104-
assertMatcher.matches("/");
110+
assertMatcher.matches(HttpMethod.GET, "/");
105111
assertMatcher.matches("/foo");
106112
}
107113

@@ -116,7 +122,7 @@ void toAnyEndpointWhenDispatcherServletPathProviderNotAvailableUsesEmptyPath() {
116122
RequestMatcher matcher = EndpointRequest.toAnyEndpoint();
117123
assertMatcher(matcher, "/actuator").matches("/actuator/foo");
118124
assertMatcher(matcher, "/actuator").matches("/actuator/bar");
119-
assertMatcher(matcher, "/actuator").matches("/actuator");
125+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator");
120126
assertMatcher(matcher, "/actuator").doesNotMatch("/actuator/baz");
121127
}
122128

@@ -151,8 +157,10 @@ void toLinksShouldOnlyMatchLinks() {
151157
RequestMatcher matcher = EndpointRequest.toLinks();
152158
assertMatcher(matcher).doesNotMatch("/actuator/foo");
153159
assertMatcher(matcher).doesNotMatch("/actuator/bar");
154-
assertMatcher(matcher).matches("/actuator");
155-
assertMatcher(matcher).matches("/actuator/");
160+
assertMatcher(matcher).matches(HttpMethod.GET, "/actuator");
161+
assertMatcher(matcher).doesNotMatch(HttpMethod.POST, "/actuator");
162+
assertMatcher(matcher).matches(HttpMethod.GET, "/actuator/");
163+
assertMatcher(matcher).doesNotMatch(HttpMethod.POST, "/actuator/");
156164
}
157165

158166
@Test
@@ -169,7 +177,7 @@ void toLinksWhenBasePathEmptyAndManagementPortDifferentShouldMatchRoot() {
169177
RequestMatcher matcher = EndpointRequest.toLinks();
170178
RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), null,
171179
WebServerNamespace.MANAGEMENT);
172-
assertMatcher.matches("/");
180+
assertMatcher.matches(HttpMethod.GET, "/");
173181
assertMatcher.doesNotMatch("/foo");
174182
}
175183

@@ -184,7 +192,7 @@ void excludeByClassShouldNotMatchExcluded() {
184192
assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo");
185193
assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz");
186194
assertMatcher(matcher).matches("/actuator/bar");
187-
assertMatcher(matcher).matches("/actuator");
195+
assertMatcher(matcher).matches(HttpMethod.GET, "/actuator");
188196
}
189197

190198
@Test
@@ -199,7 +207,7 @@ void excludeByIdShouldNotMatchExcluded() {
199207
RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("foo");
200208
assertMatcher(matcher).doesNotMatch("/actuator/foo");
201209
assertMatcher(matcher).matches("/actuator/bar");
202-
assertMatcher(matcher).matches("/actuator");
210+
assertMatcher(matcher).matches(HttpMethod.GET, "/actuator");
203211
}
204212

205213
@Test

0 commit comments

Comments
 (0)