From 184139653154675623da9cc6253221c459ed2e65 Mon Sep 17 00:00:00 2001 From: LeeJiWon Date: Thu, 2 Apr 2026 16:55:35 +0900 Subject: [PATCH] Honor HttpMethod for reactive additional endpoint paths Reactive EndpointRequest.toAdditionalPaths(...).withHttpMethod(...) stores the configured HttpMethod but does not pass it to the underlying matcher. As a result, additional endpoint paths match regardless of the configured request method. Update the reactive matcher to pass the configured method through and add a regression test to verify that only matching methods are accepted. Fixes gh-49864 Signed-off-by: LeeJiWon --- .../security/reactive/EndpointRequest.java | 2 +- .../security/reactive/EndpointRequestTests.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequest.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequest.java index f2bbd90ca23..bf4e08b0fc5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequest.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequest.java @@ -445,7 +445,7 @@ public final class EndpointRequest { .filter(Objects::nonNull) .map(this::getEndpointId) .flatMap((endpointId) -> streamAdditionalPaths(endpoints, endpointId)) - .map(PathPatternParserServerWebExchangeMatcher::new) + .map((path) -> new PathPatternParserServerWebExchangeMatcher(path, this.httpMethod)) .collect(Collectors.toCollection(ArrayList::new)); return (!CollectionUtils.isEmpty(delegateMatchers)) ? new OrServerWebExchangeMatcher(delegateMatchers) : EMPTY_MATCHER; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestTests.java index a7321f58adb..641ae66ce67 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/reactive/EndpointRequestTests.java @@ -309,6 +309,17 @@ class EndpointRequestTests { assertMatcher.matches("/additional"); } + @Test + void toAdditionalPathsWithHttpMethodShouldRespectRequestMethod() { + ServerWebExchangeMatcher matcher = EndpointRequest + .toAdditionalPaths(WebServerNamespace.SERVER, FooEndpoint.class) + .withHttpMethod(HttpMethod.POST); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, new PathMappedEndpoints("", + () -> List.of(mockEndpoint(EndpointId.of("foo"), "test", WebServerNamespace.SERVER, "/additional")))); + assertMatcher.matches(HttpMethod.POST, "/additional"); + assertMatcher.doesNotMatch(HttpMethod.GET, "/additional"); + } + @Test void toAdditionalPathsWithEndpointClassShouldNotMatchOtherPaths() { ServerWebExchangeMatcher matcher = EndpointRequest.toAdditionalPaths(WebServerNamespace.SERVER,