Skip to content

Commit 2d3273e

Browse files
dlwldnjs1009wilkinsona
authored andcommitted
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> See gh-50095
1 parent d2b62bc commit 2d3273e

4 files changed

Lines changed: 42 additions & 15 deletions

File tree

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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
@@ -373,9 +375,9 @@ protected ServerWebExchangeMatcher createDelegate(WebEndpointProperties properti
373375
String linksPath = getLinksPath(properties.getBasePath());
374376
if (linksPath != null) {
375377
List<ServerWebExchangeMatcher> linksMatchers = new ArrayList<>();
376-
linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath));
378+
linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath, HttpMethod.GET));
377379
if (!linksPath.endsWith("/")) {
378-
linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath + "/"));
380+
linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath + "/", HttpMethod.GET));
379381
}
380382
return new OrServerWebExchangeMatcher(linksMatchers);
381383
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ protected final List<RequestMatcher> getDelegateMatchers(RequestMatcherFactory r
227227
protected List<RequestMatcher> getLinksMatchers(RequestMatcherFactory requestMatcherFactory,
228228
RequestMatcherProvider matcherProvider, String linksPath) {
229229
List<RequestMatcher> linksMatchers = new ArrayList<>();
230-
linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, linksPath));
230+
linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, HttpMethod.GET, linksPath));
231231
if (!linksPath.endsWith("/")) {
232-
linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, 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

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() {
7575
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo");
7676
}
7777

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/");
85+
}
86+
7887
@Test
7988
void toAnyEndpointShouldMatchEndpointPathWithTrailingSlash() {
8089
ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint();
@@ -140,8 +149,10 @@ void toLinksShouldOnlyMatchLinks() {
140149
ServerWebExchangeMatcher matcher = EndpointRequest.toLinks();
141150
assertMatcher(matcher).doesNotMatch("/actuator/foo");
142151
assertMatcher(matcher).doesNotMatch("/actuator/bar");
143-
assertMatcher(matcher).matches("/actuator");
144-
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/");
145156
}
146157

147158
@Test

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

Lines changed: 21 additions & 9 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
@@ -75,12 +75,22 @@ void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() {
7575
assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo");
7676
}
7777

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/");
86+
}
87+
7888
@Test
7989
void toAnyEndpointShouldMatchEndpointPathWithTrailingSlash() {
8090
RequestMatcher matcher = EndpointRequest.toAnyEndpoint();
8191
assertMatcher(matcher, "/actuator").matches("/actuator/foo/");
8292
assertMatcher(matcher, "/actuator").matches("/actuator/bar/");
83-
assertMatcher(matcher, "/actuator").matches("/actuator/");
93+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator/");
8494
}
8595

8696
@Test
@@ -97,7 +107,7 @@ void toAnyEndpointWhenBasePathIsEmptyAndManagementPortDifferentShouldMatchLinks(
97107
RequestMatcher matcher = EndpointRequest.toAnyEndpoint();
98108
RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), null,
99109
WebServerNamespace.MANAGEMENT);
100-
assertMatcher.matches("/");
110+
assertMatcher.matches(HttpMethod.GET, "/");
101111
assertMatcher.matches("/foo");
102112
}
103113

@@ -112,7 +122,7 @@ void toAnyEndpointWhenDispatcherServletPathProviderNotAvailableUsesEmptyPath() {
112122
RequestMatcher matcher = EndpointRequest.toAnyEndpoint();
113123
assertMatcher(matcher, "/actuator").matches("/actuator/foo");
114124
assertMatcher(matcher, "/actuator").matches("/actuator/bar");
115-
assertMatcher(matcher, "/actuator").matches("/actuator");
125+
assertMatcher(matcher, "/actuator").matches(HttpMethod.GET, "/actuator");
116126
assertMatcher(matcher, "/actuator").doesNotMatch("/actuator/baz");
117127
}
118128

@@ -147,8 +157,10 @@ void toLinksShouldOnlyMatchLinks() {
147157
RequestMatcher matcher = EndpointRequest.toLinks();
148158
assertMatcher(matcher).doesNotMatch("/actuator/foo");
149159
assertMatcher(matcher).doesNotMatch("/actuator/bar");
150-
assertMatcher(matcher).matches("/actuator");
151-
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/");
152164
}
153165

154166
@Test
@@ -165,7 +177,7 @@ void toLinksWhenBasePathEmptyAndManagementPortDifferentShouldMatchRoot() {
165177
RequestMatcher matcher = EndpointRequest.toLinks();
166178
RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), null,
167179
WebServerNamespace.MANAGEMENT);
168-
assertMatcher.matches("/");
180+
assertMatcher.matches(HttpMethod.GET, "/");
169181
assertMatcher.doesNotMatch("/foo");
170182
}
171183

@@ -180,7 +192,7 @@ void excludeByClassShouldNotMatchExcluded() {
180192
assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo");
181193
assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz");
182194
assertMatcher(matcher).matches("/actuator/bar");
183-
assertMatcher(matcher).matches("/actuator");
195+
assertMatcher(matcher).matches(HttpMethod.GET, "/actuator");
184196
}
185197

186198
@Test
@@ -195,7 +207,7 @@ void excludeByIdShouldNotMatchExcluded() {
195207
RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding("foo");
196208
assertMatcher(matcher).doesNotMatch("/actuator/foo");
197209
assertMatcher(matcher).matches("/actuator/bar");
198-
assertMatcher(matcher).matches("/actuator");
210+
assertMatcher(matcher).matches(HttpMethod.GET, "/actuator");
199211
}
200212

201213
@Test

0 commit comments

Comments
 (0)