diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java index e5a5e0bdf2e6..a479565b1a02 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java @@ -69,6 +69,7 @@ * * @author Andy Wilkinson * @author Phillip Webb + * @author Yongjun Hong * @since 2.0.0 */ @ManagementContextConfiguration(proxyBeanMethods = false) @@ -93,6 +94,18 @@ public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpoint allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints()); String basePath = webEndpointProperties.getBasePath(); EndpointMapping endpointMapping = new EndpointMapping(basePath); + + if (basePath.isEmpty() && ManagementPortType.get(environment).equals(ManagementPortType.SAME)) { + for (ExposableWebEndpoint endpoint : webEndpoints) { + if ("/".equals(endpoint.getRootPath())) { + throw new IllegalStateException( + "Management endpoints and endpoint path are both mapped to '/' on the server port which will " + + "block access to other endpoints. Please use a different path for management endpoints or " + + "map them to a dedicated management port."); + } + } + } + boolean shouldRegisterLinksMapping = shouldRegisterLinksMapping(webEndpointProperties, environment, basePath); return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementEndpointConflictSmokeTest.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementEndpointConflictSmokeTest.java new file mode 100644 index 000000000000..8cfa7ce64bc5 --- /dev/null +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/ManagementEndpointConflictSmokeTest.java @@ -0,0 +1,27 @@ +package smoketest.actuator; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.boot.SpringApplication; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Verifies that an exception is thrown when management and server endpoint paths + * conflict. + * + * @author Yongjun Hong + */ +class ManagementEndpointConflictSmokeTest { + + @Test + void shouldThrowExceptionWhenManagementAndServerPathsConflict() { + assertThatThrownBy(() -> { + SpringApplication.run(SampleActuatorApplication.class, "--management.endpoints.web.base-path=/", + "--management.endpoints.web.path-mapping.health=/"); + }).isInstanceOf(BeanCreationException.class) + .hasMessageContaining("Management endpoints and endpoint path are both mapped to '/'"); + } + +} \ No newline at end of file