From 79f91eac561cdae9b1965a4e4945730314df771f Mon Sep 17 00:00:00 2001 From: bbbbooo Date: Wed, 11 Feb 2026 21:46:52 +0900 Subject: [PATCH 1/2] Fix EndpointRequest links matching for separate management port When management.endpoints.web.base-path is empty and management runs on a different port, EndpointRequest.toLinks() and toAnyEndpoint() do not match the links endpoint consistently. Derive the links path based on the management port type on both servlet and reactive sides, and add regression tests for each implementation. See gh-49591 Signed-off-by: bbbbooo --- .../security/reactive/EndpointRequest.java | 25 +++++++++--- .../security/servlet/EndpointRequest.java | 31 +++++++++++---- .../reactive/EndpointRequestTests.java | 39 ++++++++++++++++++- .../servlet/EndpointRequestTests.java | 39 ++++++++++++++++++- 4 files changed, 117 insertions(+), 17 deletions(-) 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 6702142749b..dcaad8d5564 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 @@ -228,6 +228,13 @@ public final class EndpointRequest { && applicationContext.getParent() == null; } + protected final String getLinksPath(String basePath) { + if (StringUtils.hasText(basePath)) { + return basePath; + } + return (this.managementPortType == ManagementPortType.DIFFERENT) ? "/" : null; + } + protected final String toString(List endpoints, String emptyValue) { return (!endpoints.isEmpty()) ? endpoints.stream() .map(this::getEndpointId) @@ -326,7 +333,8 @@ public final class EndpointRequest { streamPaths(this.includes, endpoints).forEach(paths::add); streamPaths(this.excludes, endpoints).forEach(paths::remove); List delegateMatchers = getDelegateMatchers(paths, this.httpMethod); - if (this.includeLinks && StringUtils.hasText(endpoints.getBasePath())) { + String linksPath = getLinksPath(endpoints.getBasePath()); + if (this.includeLinks && linksPath != null) { delegateMatchers.add(new LinksServerWebExchangeMatcher()); } if (delegateMatchers.isEmpty()) { @@ -362,10 +370,17 @@ public final class EndpointRequest { @Override protected ServerWebExchangeMatcher createDelegate(WebEndpointProperties properties) { - if (StringUtils.hasText(properties.getBasePath())) { - return new OrServerWebExchangeMatcher( - new PathPatternParserServerWebExchangeMatcher(properties.getBasePath()), - new PathPatternParserServerWebExchangeMatcher(properties.getBasePath() + "/")); + String linksPath = getLinksPath(properties.getBasePath()); + if (linksPath != null) { + List linksMatchers = new ArrayList<>(); + linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath)); + if ("/".equals(linksPath)) { + linksMatchers.add(new PathPatternParserServerWebExchangeMatcher("")); + } + else { + linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath + "/")); + } + return new OrServerWebExchangeMatcher(linksMatchers); } return EMPTY_MATCHER; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java index 772ed58be3b..e8a16bd185a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java @@ -225,13 +225,27 @@ public final class EndpointRequest { } protected List getLinksMatchers(RequestMatcherFactory requestMatcherFactory, - RequestMatcherProvider matcherProvider, String basePath) { + RequestMatcherProvider matcherProvider, String linksPath) { List linksMatchers = new ArrayList<>(); - linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, basePath)); - linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, basePath, "/")); + linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, linksPath)); + if (!"/".equals(linksPath)) { + linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, linksPath, "/")); + } return linksMatchers; } + protected String getLinksPath(WebApplicationContext context, String basePath) { + if (StringUtils.hasText(basePath)) { + return basePath; + } + ManagementPortType managementPortType = this.managementPortType; + if (managementPortType == null) { + managementPortType = ManagementPortType.get(context.getEnvironment()); + this.managementPortType = managementPortType; + } + return (managementPortType == ManagementPortType.DIFFERENT) ? "/" : null; + } + protected RequestMatcherProvider getRequestMatcherProvider(WebApplicationContext context) { try { return getRequestMatcherProviderBean(context); @@ -359,8 +373,9 @@ public final class EndpointRequest { List delegateMatchers = getDelegateMatchers(requestMatcherFactory, matcherProvider, paths, this.httpMethod); String basePath = endpoints.getBasePath(); - if (this.includeLinks && StringUtils.hasText(basePath)) { - delegateMatchers.addAll(getLinksMatchers(requestMatcherFactory, matcherProvider, basePath)); + String linksPath = getLinksPath(context, basePath); + if (this.includeLinks && linksPath != null) { + delegateMatchers.addAll(getLinksMatchers(requestMatcherFactory, matcherProvider, linksPath)); } if (delegateMatchers.isEmpty()) { return EMPTY_MATCHER; @@ -393,10 +408,10 @@ public final class EndpointRequest { protected RequestMatcher createDelegate(WebApplicationContext context, RequestMatcherFactory requestMatcherFactory) { WebEndpointProperties properties = context.getBean(WebEndpointProperties.class); - String basePath = properties.getBasePath(); - if (StringUtils.hasText(basePath)) { + String linksPath = getLinksPath(context, properties.getBasePath()); + if (linksPath != null) { return new OrRequestMatcher( - getLinksMatchers(requestMatcherFactory, getRequestMatcherProvider(context), basePath)); + getLinksMatchers(requestMatcherFactory, getRequestMatcherProvider(context), linksPath)); } return 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 721e576da96..c1fbc54c65e 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 @@ -20,6 +20,7 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import org.assertj.core.api.AssertDelegateTarget; import org.junit.jupiter.api.Test; @@ -35,6 +36,7 @@ import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.web.context.WebServerApplicationContext; import org.springframework.boot.web.server.WebServer; import org.springframework.context.support.StaticApplicationContext; +import org.springframework.core.env.MapPropertySource; import org.springframework.http.HttpMethod; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; @@ -91,6 +93,15 @@ class EndpointRequestTests { assertMatcher.matches("/bar"); } + @Test + void toAnyEndpointWhenBasePathIsEmptyAndManagementPortDifferentShouldMatchLinks() { + ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), + WebServerNamespace.MANAGEMENT, true); + assertMatcher.matches("/"); + assertMatcher.matches("/foo"); + } + @Test void toAnyEndpointShouldNotMatchOtherPath() { ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); @@ -143,6 +154,15 @@ class EndpointRequestTests { assertMatcher.doesNotMatch("/"); } + @Test + void toLinksWhenBasePathEmptyAndManagementPortDifferentShouldMatchRoot() { + ServerWebExchangeMatcher matcher = EndpointRequest.toLinks(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), + WebServerNamespace.MANAGEMENT, true); + assertMatcher.matches("/"); + assertMatcher.doesNotMatch("/foo"); + } + @Test void excludeByClassShouldNotMatchExcluded() { ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint() @@ -325,10 +345,25 @@ class EndpointRequestTests { private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, PathMappedEndpoints pathMappedEndpoints, WebServerNamespace namespace) { + return assertMatcher(matcher, pathMappedEndpoints, namespace, false); + } + + private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, + PathMappedEndpoints pathMappedEndpoints, WebServerNamespace namespace, boolean managementPortDifferent) { StaticApplicationContext context = new StaticApplicationContext(); if (namespace != null && !WebServerNamespace.SERVER.equals(namespace)) { - NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); - context.setParent(parentContext); + if (managementPortDifferent) { + context = new NamedStaticWebApplicationContext(namespace); + } + else { + NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); + context.setParent(parentContext); + } + } + if (managementPortDifferent) { + context.getEnvironment() + .getPropertySources() + .addFirst(new MapPropertySource("test", Map.of("management.server.port", 0))); } context.registerBean(WebEndpointProperties.class); if (pathMappedEndpoints != null) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java index 0a16d3cade7..6e1c21029e9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java @@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.security.servlet; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import jakarta.servlet.http.HttpServletRequest; import org.assertj.core.api.AssertDelegateTarget; @@ -36,6 +37,7 @@ import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.web.context.WebServerApplicationContext; import org.springframework.boot.web.server.WebServer; +import org.springframework.core.env.MapPropertySource; import org.springframework.http.HttpMethod; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockServletContext; @@ -91,6 +93,15 @@ class EndpointRequestTests { assertMatcher.matches("/bar"); } + @Test + void toAnyEndpointWhenBasePathIsEmptyAndManagementPortDifferentShouldMatchLinks() { + RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), null, + WebServerNamespace.MANAGEMENT, true); + assertMatcher.matches("/"); + assertMatcher.matches("/foo"); + } + @Test void toAnyEndpointShouldNotMatchOtherPath() { RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); @@ -150,6 +161,15 @@ class EndpointRequestTests { assertMatcher.doesNotMatch("/"); } + @Test + void toLinksWhenBasePathEmptyAndManagementPortDifferentShouldMatchRoot() { + RequestMatcher matcher = EndpointRequest.toLinks(); + RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), null, + WebServerNamespace.MANAGEMENT, true); + assertMatcher.matches("/"); + assertMatcher.doesNotMatch("/foo"); + } + @Test void excludeByClassShouldNotMatchExcluded() { RequestMatcher matcher = EndpointRequest.toAnyEndpoint().excluding(FooEndpoint.class, BazServletEndpoint.class); @@ -350,10 +370,25 @@ class EndpointRequestTests { private RequestMatcherAssert assertMatcher(RequestMatcher matcher, PathMappedEndpoints pathMappedEndpoints, RequestMatcherProvider matcherProvider, WebServerNamespace namespace) { + return assertMatcher(matcher, pathMappedEndpoints, matcherProvider, namespace, false); + } + + private RequestMatcherAssert assertMatcher(RequestMatcher matcher, PathMappedEndpoints pathMappedEndpoints, + RequestMatcherProvider matcherProvider, WebServerNamespace namespace, boolean managementPortDifferent) { StaticWebApplicationContext context = new StaticWebApplicationContext(); if (namespace != null && !WebServerNamespace.SERVER.equals(namespace)) { - NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); - context.setParent(parentContext); + if (managementPortDifferent) { + context = new NamedStaticWebApplicationContext(namespace); + } + else { + NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); + context.setParent(parentContext); + } + } + if (managementPortDifferent) { + context.getEnvironment() + .getPropertySources() + .addFirst(new MapPropertySource("test", Map.of("management.server.port", 0))); } context.registerBean(WebEndpointProperties.class); if (pathMappedEndpoints != null) { From a148983e7fe8ae58064390e7d64f3fa70f38e878 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 16 Mar 2026 16:53:54 +0000 Subject: [PATCH 2/2] Polish "Fix EndpointRequest links matching for separate management port" See gh-49591 Signed-off-by: Andy Wilkinson --- .../security/reactive/EndpointRequest.java | 5 +- .../security/servlet/EndpointRequest.java | 2 +- .../reactive/EndpointRequestTests.java | 30 +++----- .../servlet/EndpointRequestTests.java | 30 +++----- ...ractSampleActuatorCustomSecurityTests.java | 74 ++++++++---------- .../CustomServletPathSampleActuatorTests.java | 4 +- ...asePathSampleActuatorApplicationTests.java | 77 +++++++++++++++++++ ...sePathSampleActuatorApplicationTests.java} | 12 +-- ...CustomServletPathSampleActuatorTests.java} | 10 +-- ...ctuatorCustomSecurityApplicationTests.java | 9 +-- 10 files changed, 146 insertions(+), 107 deletions(-) create mode 100644 spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomBasePathAndWebEndpointsBasePathSampleActuatorApplicationTests.java rename spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/{ManagementPortAndPathSampleActuatorApplicationTests.java => ManagementServerWithCustomBasePathSampleActuatorApplicationTests.java} (85%) rename spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/{ManagementPortCustomServletPathSampleActuatorTests.java => ManagementServerWithCustomServletPathSampleActuatorTests.java} (86%) 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 dcaad8d5564..5e09360669b 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 @@ -374,10 +374,7 @@ public final class EndpointRequest { if (linksPath != null) { List linksMatchers = new ArrayList<>(); linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath)); - if ("/".equals(linksPath)) { - linksMatchers.add(new PathPatternParserServerWebExchangeMatcher("")); - } - else { + if (!linksPath.endsWith("/")) { linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath + "/")); } return new OrServerWebExchangeMatcher(linksMatchers); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java index e8a16bd185a..f0e5f28734e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequest.java @@ -228,7 +228,7 @@ public final class EndpointRequest { RequestMatcherProvider matcherProvider, String linksPath) { List linksMatchers = new ArrayList<>(); linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, linksPath)); - if (!"/".equals(linksPath)) { + if (!linksPath.endsWith("/")) { linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, linksPath, "/")); } return linksMatchers; 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 c1fbc54c65e..151ea82b28c 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 @@ -20,7 +20,6 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; import org.assertj.core.api.AssertDelegateTarget; import org.junit.jupiter.api.Test; @@ -33,10 +32,10 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoint; import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.web.context.WebServerApplicationContext; import org.springframework.boot.web.server.WebServer; import org.springframework.context.support.StaticApplicationContext; -import org.springframework.core.env.MapPropertySource; import org.springframework.http.HttpMethod; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; @@ -97,7 +96,7 @@ class EndpointRequestTests { void toAnyEndpointWhenBasePathIsEmptyAndManagementPortDifferentShouldMatchLinks() { ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint(); RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), - WebServerNamespace.MANAGEMENT, true); + WebServerNamespace.MANAGEMENT); assertMatcher.matches("/"); assertMatcher.matches("/foo"); } @@ -158,7 +157,7 @@ class EndpointRequestTests { void toLinksWhenBasePathEmptyAndManagementPortDifferentShouldMatchRoot() { ServerWebExchangeMatcher matcher = EndpointRequest.toLinks(); RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), - WebServerNamespace.MANAGEMENT, true); + WebServerNamespace.MANAGEMENT); assertMatcher.matches("/"); assertMatcher.doesNotMatch("/foo"); } @@ -345,25 +344,14 @@ class EndpointRequestTests { private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, PathMappedEndpoints pathMappedEndpoints, WebServerNamespace namespace) { - return assertMatcher(matcher, pathMappedEndpoints, namespace, false); - } - - private RequestMatcherAssert assertMatcher(ServerWebExchangeMatcher matcher, - PathMappedEndpoints pathMappedEndpoints, WebServerNamespace namespace, boolean managementPortDifferent) { - StaticApplicationContext context = new StaticApplicationContext(); + StaticWebApplicationContext context; if (namespace != null && !WebServerNamespace.SERVER.equals(namespace)) { - if (managementPortDifferent) { - context = new NamedStaticWebApplicationContext(namespace); - } - else { - NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); - context.setParent(parentContext); - } + context = new NamedStaticWebApplicationContext(namespace); + context.setParent(new StaticWebApplicationContext()); + TestPropertyValues.of("management.server.port=0").applyTo(context); } - if (managementPortDifferent) { - context.getEnvironment() - .getPropertySources() - .addFirst(new MapPropertySource("test", Map.of("management.server.port", 0))); + else { + context = new StaticWebApplicationContext(); } context.registerBean(WebEndpointProperties.class); if (pathMappedEndpoints != null) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java index 6e1c21029e9..7a7620f2564 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/security/servlet/EndpointRequestTests.java @@ -19,7 +19,6 @@ package org.springframework.boot.actuate.autoconfigure.security.servlet; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; import jakarta.servlet.http.HttpServletRequest; import org.assertj.core.api.AssertDelegateTarget; @@ -35,9 +34,9 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoint; import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.web.context.WebServerApplicationContext; import org.springframework.boot.web.server.WebServer; -import org.springframework.core.env.MapPropertySource; import org.springframework.http.HttpMethod; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockServletContext; @@ -97,7 +96,7 @@ class EndpointRequestTests { void toAnyEndpointWhenBasePathIsEmptyAndManagementPortDifferentShouldMatchLinks() { RequestMatcher matcher = EndpointRequest.toAnyEndpoint(); RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), null, - WebServerNamespace.MANAGEMENT, true); + WebServerNamespace.MANAGEMENT); assertMatcher.matches("/"); assertMatcher.matches("/foo"); } @@ -165,7 +164,7 @@ class EndpointRequestTests { void toLinksWhenBasePathEmptyAndManagementPortDifferentShouldMatchRoot() { RequestMatcher matcher = EndpointRequest.toLinks(); RequestMatcherAssert assertMatcher = assertMatcher(matcher, mockPathMappedEndpoints(""), null, - WebServerNamespace.MANAGEMENT, true); + WebServerNamespace.MANAGEMENT); assertMatcher.matches("/"); assertMatcher.doesNotMatch("/foo"); } @@ -370,25 +369,14 @@ class EndpointRequestTests { private RequestMatcherAssert assertMatcher(RequestMatcher matcher, PathMappedEndpoints pathMappedEndpoints, RequestMatcherProvider matcherProvider, WebServerNamespace namespace) { - return assertMatcher(matcher, pathMappedEndpoints, matcherProvider, namespace, false); - } - - private RequestMatcherAssert assertMatcher(RequestMatcher matcher, PathMappedEndpoints pathMappedEndpoints, - RequestMatcherProvider matcherProvider, WebServerNamespace namespace, boolean managementPortDifferent) { - StaticWebApplicationContext context = new StaticWebApplicationContext(); + StaticWebApplicationContext context; if (namespace != null && !WebServerNamespace.SERVER.equals(namespace)) { - if (managementPortDifferent) { - context = new NamedStaticWebApplicationContext(namespace); - } - else { - NamedStaticWebApplicationContext parentContext = new NamedStaticWebApplicationContext(namespace); - context.setParent(parentContext); - } + context = new NamedStaticWebApplicationContext(namespace); + context.setParent(new StaticWebApplicationContext()); + TestPropertyValues.of("management.server.port=0").applyTo(context); } - if (managementPortDifferent) { - context.getEnvironment() - .getPropertySources() - .addFirst(new MapPropertySource("test", Map.of("management.server.port", 0))); + else { + context = new StaticWebApplicationContext(); } context.registerBean(WebEndpointProperties.class); if (pathMappedEndpoints != null) { diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java index bc9f315fd36..7abb0283fe8 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/AbstractSampleActuatorCustomSecurityTests.java @@ -37,7 +37,7 @@ abstract class AbstractSampleActuatorCustomSecurityTests { abstract String getPath(); - abstract String getManagementPath(); + abstract String getActuatorPath(); abstract Environment getEnvironment(); @@ -58,119 +58,110 @@ abstract class AbstractSampleActuatorCustomSecurityTests { @Test void actuatorInsecureEndpoint() { - ResponseEntity entity = restTemplate().getForEntity(getManagementPath() + "/actuator/health", - String.class); + ResponseEntity entity = restTemplate().getForEntity(getActuatorPath() + "/health", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getBody()).contains("\"status\":\"UP\""); - entity = restTemplate().getForEntity(getManagementPath() + "/actuator/health/diskSpace", String.class); + entity = restTemplate().getForEntity(getActuatorPath() + "/health/diskSpace", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getBody()).contains("\"status\":\"UP\""); } @Test void actuatorLinksWithAnonymous() { - ResponseEntity entity = restTemplate().getForEntity(getManagementPath() + "/actuator", Object.class); + ResponseEntity entity = restTemplate().getForEntity(getActuatorPath(), Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); - entity = restTemplate().getForEntity(getManagementPath() + "/actuator/", Object.class); + entity = restTemplate().getForEntity(getActuatorPath() + "/", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); } @Test void actuatorLinksWithUnauthorizedUser() { - ResponseEntity entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator", - Object.class); + ResponseEntity entity = userRestTemplate().getForEntity(getActuatorPath(), Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/", Object.class); + entity = userRestTemplate().getForEntity(getActuatorPath() + "/", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); } @Test void actuatorLinksWithAuthorizedUser() { - ResponseEntity entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator", - Object.class); + ResponseEntity entity = adminRestTemplate().getForEntity(getActuatorPath(), Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - adminRestTemplate().getForEntity(getManagementPath() + "/actuator/", Object.class); + adminRestTemplate().getForEntity(getActuatorPath() + "/", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); } @Test void actuatorSecureEndpointWithAnonymous() { - ResponseEntity entity = restTemplate().getForEntity(getManagementPath() + "/actuator/env", - Object.class); + ResponseEntity entity = restTemplate().getForEntity(getActuatorPath() + "/env", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); - entity = restTemplate().getForEntity( - getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", Object.class); + entity = restTemplate().getForEntity(getActuatorPath() + "/env/management.endpoints.web.exposure.include", + Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); } @Test void actuatorSecureEndpointWithUnauthorizedUser() { - ResponseEntity entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/env", - Object.class); + ResponseEntity entity = userRestTemplate().getForEntity(getActuatorPath() + "/env", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - entity = userRestTemplate().getForEntity( - getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", Object.class); + entity = userRestTemplate().getForEntity(getActuatorPath() + "/env/management.endpoints.web.exposure.include", + Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); } @Test void actuatorSecureEndpointWithAuthorizedUser() { - ResponseEntity entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/env", - Object.class); + ResponseEntity entity = adminRestTemplate().getForEntity(getActuatorPath() + "/env", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/env/", Object.class); + entity = adminRestTemplate().getForEntity(getActuatorPath() + "/env/", Object.class); // EndpointRequest matches the trailing slash but MVC doesn't assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); - entity = adminRestTemplate().getForEntity( - getManagementPath() + "/actuator/env/management.endpoints.web.exposure.include", Object.class); + entity = adminRestTemplate().getForEntity(getActuatorPath() + "/env/management.endpoints.web.exposure.include", + Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); } @Test void secureServletEndpointWithAnonymous() { - ResponseEntity entity = restTemplate().getForEntity(getManagementPath() + "/actuator/se1", - String.class); + ResponseEntity entity = restTemplate().getForEntity(getActuatorPath() + "/se1", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); - entity = restTemplate().getForEntity(getManagementPath() + "/actuator/se1/list", String.class); + entity = restTemplate().getForEntity(getActuatorPath() + "/se1/list", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); } @Test void secureServletEndpointWithUnauthorizedUser() { - ResponseEntity entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/se1", - String.class); + ResponseEntity entity = userRestTemplate().getForEntity(getActuatorPath() + "/se1", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); - entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/se1/list", String.class); + entity = userRestTemplate().getForEntity(getActuatorPath() + "/se1/list", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); } @Test void secureServletEndpointWithAuthorizedUser() { - ResponseEntity entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/se1", - String.class); + ResponseEntity entity = adminRestTemplate().getForEntity(getActuatorPath() + "/se1", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - entity = adminRestTemplate().getForEntity(getManagementPath() + "/actuator/se1/list", String.class); + entity = adminRestTemplate().getForEntity(getActuatorPath() + "/se1/list", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); } @Test void actuatorCustomMvcSecureEndpointWithAnonymous() { - ResponseEntity entity = restTemplate() - .getForEntity(getManagementPath() + "/actuator/example/echo?text={t}", String.class, "test"); + ResponseEntity entity = restTemplate().getForEntity(getActuatorPath() + "/example/echo?text={t}", + String.class, "test"); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); } @Test void actuatorCustomMvcSecureEndpointWithUnauthorizedUser() { - ResponseEntity entity = userRestTemplate() - .getForEntity(getManagementPath() + "/actuator/example/echo?text={t}", String.class, "test"); + ResponseEntity entity = userRestTemplate().getForEntity(getActuatorPath() + "/example/echo?text={t}", + String.class, "test"); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); } @Test void actuatorCustomMvcSecureEndpointWithAuthorizedUser() { - ResponseEntity entity = adminRestTemplate() - .getForEntity(getManagementPath() + "/actuator/example/echo?text={t}", String.class, "test"); + ResponseEntity entity = adminRestTemplate().getForEntity(getActuatorPath() + "/example/echo?text={t}", + String.class, "test"); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getBody()).isEqualTo("test"); assertThat(entity.getHeaders().getFirst("echo")).isEqualTo("test"); @@ -178,8 +169,7 @@ abstract class AbstractSampleActuatorCustomSecurityTests { @Test void actuatorExcludedFromEndpointRequestMatcher() { - ResponseEntity entity = userRestTemplate().getForEntity(getManagementPath() + "/actuator/mappings", - Object.class); + ResponseEntity entity = userRestTemplate().getForEntity(getActuatorPath() + "/mappings", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); } diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java index ebc95a8a2bf..7dda1f9e907 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/CustomServletPathSampleActuatorTests.java @@ -42,8 +42,8 @@ class CustomServletPathSampleActuatorTests extends AbstractSampleActuatorCustomS } @Override - String getManagementPath() { - return "http://localhost:" + this.port + "/example"; + String getActuatorPath() { + return "http://localhost:" + this.port + "/example/actuator"; } @Override diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomBasePathAndWebEndpointsBasePathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomBasePathAndWebEndpointsBasePathSampleActuatorApplicationTests.java new file mode 100644 index 00000000000..636a59291ab --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomBasePathAndWebEndpointsBasePathSampleActuatorApplicationTests.java @@ -0,0 +1,77 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package smoketest.actuator.customsecurity; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for a separate management server with custom base path and web + * endpoints base path. + * + * @author Dave Syer + * @author Madhura Bhave + */ +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "management.server.port=0", + "management.server.base-path=/management", "management.endpoints.web.base-path=/" }) +class ManagementServerWithCustomBasePathAndWebEndpointsBasePathSampleActuatorApplicationTests + extends AbstractSampleActuatorCustomSecurityTests { + + @LocalServerPort + private int port; + + @LocalManagementPort + private int managementPort; + + @Autowired + private Environment environment; + + @Test + void testMissing() { + ResponseEntity entity = new TestRestTemplate("admin", "admin") + .getForEntity(getActuatorPath() + "/missing", String.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + assertThat(entity.getBody()).contains("\"status\":404"); + } + + @Override + String getPath() { + return "http://localhost:" + this.port; + } + + @Override + String getActuatorPath() { + return "http://localhost:" + this.managementPort + "/management"; + } + + @Override + Environment getEnvironment() { + return this.environment; + } + +} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomBasePathSampleActuatorApplicationTests.java similarity index 85% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomBasePathSampleActuatorApplicationTests.java index aa08feef9ee..353902eedbc 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortAndPathSampleActuatorApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomBasePathSampleActuatorApplicationTests.java @@ -31,15 +31,15 @@ import org.springframework.http.ResponseEntity; import static org.assertj.core.api.Assertions.assertThat; /** - * Integration tests for separate management and main service ports with custom management - * context path. + * Integration tests for a separate management server with a custom base path. * * @author Dave Syer * @author Madhura Bhave */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "management.server.port=0", "management.server.base-path=/management" }) -class ManagementPortAndPathSampleActuatorApplicationTests extends AbstractSampleActuatorCustomSecurityTests { +class ManagementServerWithCustomBasePathSampleActuatorApplicationTests + extends AbstractSampleActuatorCustomSecurityTests { @LocalServerPort private int port; @@ -53,7 +53,7 @@ class ManagementPortAndPathSampleActuatorApplicationTests extends AbstractSample @Test void testMissing() { ResponseEntity entity = new TestRestTemplate("admin", "admin") - .getForEntity("http://localhost:" + this.managementPort + "/management/actuator/missing", String.class); + .getForEntity(getActuatorPath() + "/missing", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); assertThat(entity.getBody()).contains("\"status\":404"); } @@ -64,8 +64,8 @@ class ManagementPortAndPathSampleActuatorApplicationTests extends AbstractSample } @Override - String getManagementPath() { - return "http://localhost:" + this.managementPort + "/management"; + String getActuatorPath() { + return "http://localhost:" + this.managementPort + "/management/actuator"; } @Override diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomServletPathSampleActuatorTests.java similarity index 86% rename from spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java rename to spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomServletPathSampleActuatorTests.java index da042e70995..2fb5aea4684 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementPortCustomServletPathSampleActuatorTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/ManagementServerWithCustomServletPathSampleActuatorTests.java @@ -30,14 +30,14 @@ import org.springframework.http.ResponseEntity; import static org.assertj.core.api.Assertions.assertThat; /** - * Integration tests for separate management and main service ports with custom dispatcher - * servlet path. + * Integration tests for a separate management server with a custom dispatcher servlet + * path. * * @author Madhura Bhave */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "management.server.port=0", "spring.mvc.servlet.path=/example" }) -class ManagementPortCustomServletPathSampleActuatorTests extends AbstractSampleActuatorCustomSecurityTests { +class ManagementServerWithCustomServletPathSampleActuatorTests extends AbstractSampleActuatorCustomSecurityTests { @LocalServerPort private int port; @@ -61,8 +61,8 @@ class ManagementPortCustomServletPathSampleActuatorTests extends AbstractSampleA } @Override - String getManagementPath() { - return "http://localhost:" + this.managementPort; + String getActuatorPath() { + return "http://localhost:" + this.managementPort + "/actuator"; } @Override diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java index 7227fa42028..4be29ed6cee 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator-custom-security/src/test/java/smoketest/actuator/customsecurity/SampleActuatorCustomSecurityApplicationTests.java @@ -52,8 +52,8 @@ class SampleActuatorCustomSecurityApplicationTests extends AbstractSampleActuato } @Override - String getManagementPath() { - return "http://localhost:" + this.port; + String getActuatorPath() { + return "http://localhost:" + this.port + "/actuator"; } @Override @@ -72,10 +72,9 @@ class SampleActuatorCustomSecurityApplicationTests extends AbstractSampleActuato @Test void mvcMatchersCanBeUsedToSecureActuators() { - ResponseEntity entity = beansRestTemplate().getForEntity(getManagementPath() + "/actuator/beans", - Object.class); + ResponseEntity entity = beansRestTemplate().getForEntity(getActuatorPath() + "/beans", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - entity = beansRestTemplate().getForEntity(getManagementPath() + "/actuator/beans/", Object.class); + entity = beansRestTemplate().getForEntity(getActuatorPath() + "/beans/", Object.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); }