Skip to content

Commit 03eb75f

Browse files
committed
Merge pull request #50095 from dlwldnjs1009
* gh-50095: Always match the links endpoint with GET Closes gh-50095
2 parents d2b62bc + 2d3273e commit 03eb75f

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)