diff --git a/configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/RecordParameterPropertyDescriptor.java b/configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/RecordParameterPropertyDescriptor.java index dfec811c02d8..f17f8e1f4036 100644 --- a/configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/RecordParameterPropertyDescriptor.java +++ b/configuration-metadata/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/RecordParameterPropertyDescriptor.java @@ -54,7 +54,8 @@ protected ItemDeprecation resolveItemDeprecation(MetadataGenerationEnvironment e @Override protected boolean isMarkedAsNested(MetadataGenerationEnvironment environment) { - return environment.getNestedConfigurationPropertyAnnotation(this.recordComponent) != null; + return environment.getNestedConfigurationPropertyAnnotation(this.recordComponent) != null + || environment.getNestedConfigurationPropertyAnnotation(getGetter()) != null; } @Override diff --git a/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/web/reactive/EndpointRequest.java b/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/web/reactive/EndpointRequest.java index ea69c5d8101a..44d374d2bd71 100644 --- a/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/web/reactive/EndpointRequest.java +++ b/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/web/reactive/EndpointRequest.java @@ -120,7 +120,7 @@ public static EndpointServerWebExchangeMatcher to(String... endpoints) { * @return the configured {@link ServerWebExchangeMatcher} */ public static LinksServerWebExchangeMatcher toLinks() { - return new LinksServerWebExchangeMatcher(); + return new LinksServerWebExchangeMatcher(null); } /** @@ -344,7 +344,7 @@ protected ServerWebExchangeMatcher createDelegate(PathMappedEndpoints endpoints) List delegateMatchers = getDelegateMatchers(paths, this.httpMethod); String linksPath = getLinksPath(endpoints.getBasePath()); if (this.includeLinks && linksPath != null) { - delegateMatchers.add(new LinksServerWebExchangeMatcher()); + delegateMatchers.add(new LinksServerWebExchangeMatcher(this.httpMethod)); } if (delegateMatchers.isEmpty()) { return EMPTY_MATCHER; @@ -373,8 +373,11 @@ public String toString() { */ public static final class LinksServerWebExchangeMatcher extends AbstractWebExchangeMatcher { - private LinksServerWebExchangeMatcher() { + private final @Nullable HttpMethod httpMethod; + + private LinksServerWebExchangeMatcher(@Nullable HttpMethod httpMethod) { super(WebEndpointProperties.class); + this.httpMethod = httpMethod; } @Override @@ -382,9 +385,9 @@ protected ServerWebExchangeMatcher createDelegate(WebEndpointProperties properti String linksPath = getLinksPath(properties.getBasePath()); if (linksPath != null) { List linksMatchers = new ArrayList<>(); - linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath)); + linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath, this.httpMethod)); if (!linksPath.endsWith("/")) { - linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath + "/")); + linksMatchers.add(new PathPatternParserServerWebExchangeMatcher(linksPath + "/", this.httpMethod)); } return new OrServerWebExchangeMatcher(linksMatchers); } diff --git a/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/web/servlet/EndpointRequest.java b/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/web/servlet/EndpointRequest.java index f36a7461108e..f0081303bd12 100644 --- a/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/web/servlet/EndpointRequest.java +++ b/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/actuate/web/servlet/EndpointRequest.java @@ -224,11 +224,11 @@ protected final List getDelegateMatchers(RequestMatcherFactory r } protected List getLinksMatchers(RequestMatcherFactory requestMatcherFactory, - RequestMatcherProvider matcherProvider, String linksPath) { + RequestMatcherProvider matcherProvider, String linksPath, @Nullable HttpMethod httpMethod) { List linksMatchers = new ArrayList<>(); - linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, linksPath)); + linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, httpMethod, linksPath)); if (!linksPath.endsWith("/")) { - linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, null, linksPath, "/")); + linksMatchers.add(requestMatcherFactory.antPath(matcherProvider, httpMethod, linksPath, "/")); } return linksMatchers; } @@ -357,7 +357,7 @@ protected RequestMatcher createDelegate(WebApplicationContext context, String basePath = endpoints.getBasePath(); String linksPath = getLinksPath(context, basePath); if (this.includeLinks && linksPath != null) { - delegateMatchers.addAll(getLinksMatchers(requestMatcherFactory, matcherProvider, linksPath)); + delegateMatchers.addAll(getLinksMatchers(requestMatcherFactory, matcherProvider, linksPath, this.httpMethod)); } if (delegateMatchers.isEmpty()) { return EMPTY_MATCHER; @@ -393,7 +393,7 @@ protected RequestMatcher createDelegate(WebApplicationContext context, String linksPath = getLinksPath(context, properties.getBasePath()); if (linksPath != null) { return new OrRequestMatcher( - getLinksMatchers(requestMatcherFactory, getRequestMatcherProvider(context), linksPath)); + getLinksMatchers(requestMatcherFactory, getRequestMatcherProvider(context), linksPath, null)); } return EMPTY_MATCHER; } diff --git a/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/web/reactive/EndpointRequestTests.java b/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/web/reactive/EndpointRequestTests.java index 28b4db4066af..cf8554d4e84f 100644 --- a/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/web/reactive/EndpointRequestTests.java +++ b/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/web/reactive/EndpointRequestTests.java @@ -75,6 +75,10 @@ void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() { ServerWebExchangeMatcher matcher = EndpointRequest.toAnyEndpoint().withHttpMethod(HttpMethod.POST); assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/foo"); assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo"); + assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator"); + assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator"); + assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/"); + assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/"); } @Test diff --git a/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/web/servlet/EndpointRequestTests.java b/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/web/servlet/EndpointRequestTests.java index b5787b4be95a..5c04f9032734 100644 --- a/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/web/servlet/EndpointRequestTests.java +++ b/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/actuate/web/servlet/EndpointRequestTests.java @@ -74,6 +74,10 @@ void toAnyEndpointWithHttpMethodShouldRespectRequestMethod() { .withHttpMethod(HttpMethod.POST); assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/foo"); assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/foo"); + assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator"); + assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator"); + assertMatcher(matcher, "/actuator").matches(HttpMethod.POST, "/actuator/"); + assertMatcher(matcher, "/actuator").doesNotMatch(HttpMethod.GET, "/actuator/"); } @Test