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 402becd8f7c..c79bb7e3ebc 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 @@ -34,7 +34,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointPr import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; import org.springframework.boot.security.reactive.ApplicationContextServerWebExchangeMatcher; -import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.security.web.server.util.matcher.OrServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; @@ -219,7 +219,7 @@ public final class EndpointRequest { } private String getEndpointId(Class source) { - Endpoint annotation = AnnotationUtils.findAnnotation(source, Endpoint.class); + Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source, Endpoint.class); Assert.state(annotation != null, () -> "Class " + source + " is not annotated with @Endpoint"); return annotation.id(); 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 79894be539c..042d556483e 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 @@ -35,7 +35,7 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathProvider; import org.springframework.boot.security.servlet.ApplicationContextRequestMatcher; -import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; @@ -238,7 +238,7 @@ public final class EndpointRequest { } private String getEndpointId(Class source) { - Endpoint annotation = AnnotationUtils.findAnnotation(source, Endpoint.class); + Endpoint annotation = AnnotatedElementUtils.getMergedAnnotation(source, Endpoint.class); Assert.state(annotation != null, () -> "Class " + source + " is not annotated with @Endpoint"); return annotation.id(); 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 3c6dbb475f6..85ff64afa43 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 @@ -28,6 +28,7 @@ import org.springframework.boot.actuate.endpoint.Operation; 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.annotation.ServletEndpoint; import org.springframework.context.support.StaticApplicationContext; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; @@ -117,8 +118,14 @@ public class EndpointRequestTests { @Test public void excludeByClassShouldNotMatchExcluded() { ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint() - .excluding(FooEndpoint.class); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); + .excluding(FooEndpoint.class, BazServletEndpoint.class); + List> endpoints = new ArrayList<>(); + endpoints.add(mockEndpoint("foo", "foo")); + endpoints.add(mockEndpoint("bar", "bar")); + endpoints.add(mockEndpoint("baz", "baz")); + PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator", () -> endpoints); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo"); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz"); assertMatcher(matcher).matches("/actuator/bar"); assertMatcher(matcher).matches("/actuator"); } @@ -280,6 +287,11 @@ public class EndpointRequestTests { } + @ServletEndpoint(id = "baz") + private static class BazServletEndpoint { + + } + interface TestEndpoint extends ExposableEndpoint, PathMappedEndpoint { } 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 603855861b7..e44eaf1a9d7 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 @@ -30,6 +30,7 @@ import org.springframework.boot.actuate.endpoint.Operation; 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.annotation.ServletEndpoint; import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathProvider; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockServletContext; @@ -139,8 +140,14 @@ public class EndpointRequestTests { @Test public void excludeByClassShouldNotMatchExcluded() { RequestMatcher matcher = EndpointRequest.toAnyEndpoint() - .excluding(FooEndpoint.class); - assertMatcher(matcher).doesNotMatch("/actuator/foo"); + .excluding(FooEndpoint.class, BazServletEndpoint.class); + List> endpoints = new ArrayList<>(); + endpoints.add(mockEndpoint("foo", "foo")); + endpoints.add(mockEndpoint("bar", "bar")); + endpoints.add(mockEndpoint("baz", "baz")); + PathMappedEndpoints pathMappedEndpoints = new PathMappedEndpoints("/actuator", () -> endpoints); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/foo"); + assertMatcher(matcher, pathMappedEndpoints).doesNotMatch("/actuator/baz"); assertMatcher(matcher).matches("/actuator/bar"); assertMatcher(matcher).matches("/actuator"); } @@ -311,6 +318,11 @@ public class EndpointRequestTests { } + @ServletEndpoint(id = "baz") + private static class BazServletEndpoint { + + } + interface TestEndpoint extends ExposableEndpoint, PathMappedEndpoint { }