Skip to content

Commit 32444fe

Browse files
committed
Merge branch '2.7.x' into 3.0.x
Closes gh-35086
2 parents 6933796 + 3522714 commit 32444fe

File tree

8 files changed

+125
-39
lines changed

8 files changed

+125
-39
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
3535
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints;
3636
import org.springframework.boot.actuate.endpoint.EndpointId;
37+
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
3738
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
3839
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
3940
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
@@ -64,12 +65,15 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH
6465

6566
private final EndpointLinksResolver linksResolver;
6667

68+
private final Collection<ExposableEndpoint<?>> allEndpoints;
69+
6770
CloudFoundryWebFluxEndpointHandlerMapping(EndpointMapping endpointMapping,
6871
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
6972
CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor,
70-
EndpointLinksResolver linksResolver) {
73+
Collection<ExposableEndpoint<?>> allEndpoints) {
7174
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, true);
72-
this.linksResolver = linksResolver;
75+
this.linksResolver = new EndpointLinksResolver(allEndpoints);
76+
this.allEndpoints = allEndpoints;
7377
this.securityInterceptor = securityInterceptor;
7478
}
7579

@@ -84,6 +88,10 @@ protected LinksHandler getLinksHandler() {
8488
return new CloudFoundryLinksHandler();
8589
}
8690

91+
Collection<ExposableEndpoint<?>> getAllEndpoints() {
92+
return this.allEndpoints;
93+
}
94+
8795
class CloudFoundryLinksHandler implements LinksHandler {
8896

8997
@Override

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfiguration.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
3333
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
3434
import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper;
35-
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
3635
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
3736
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
3837
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
38+
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
3939
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
4040
import org.springframework.boot.actuate.health.HealthEndpoint;
4141
import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension;
@@ -80,6 +80,8 @@
8080
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)
8181
public class ReactiveCloudFoundryActuatorAutoConfiguration {
8282

83+
private static final String BASE_PATH = "/cloudfoundryapplication";
84+
8385
@Bean
8486
@ConditionalOnMissingBean
8587
@ConditionalOnAvailableEndpoint
@@ -115,9 +117,8 @@ public CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebFluxEndpointHand
115117
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
116118
allEndpoints.addAll(webEndpoints);
117119
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
118-
return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping("/cloudfoundryapplication"),
119-
webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor,
120-
new EndpointLinksResolver(allEndpoints));
120+
return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping(BASE_PATH), webEndpoints,
121+
endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints);
121122
}
122123

123124
private CloudFoundrySecurityInterceptor getSecurityInterceptor(WebClient.Builder webClientBuilder,
@@ -153,25 +154,33 @@ private CorsConfiguration getCorsConfiguration() {
153154
static class IgnoredPathsSecurityConfiguration {
154155

155156
@Bean
156-
WebFilterChainPostProcessor webFilterChainPostProcessor() {
157-
return new WebFilterChainPostProcessor();
157+
WebFilterChainPostProcessor webFilterChainPostProcessor(
158+
CloudFoundryWebFluxEndpointHandlerMapping handlerMapping) {
159+
return new WebFilterChainPostProcessor(handlerMapping);
158160
}
159161

160162
}
161163

162164
static class WebFilterChainPostProcessor implements BeanPostProcessor {
163165

166+
private final PathMappedEndpoints pathMappedEndpoints;
167+
168+
WebFilterChainPostProcessor(CloudFoundryWebFluxEndpointHandlerMapping handlerMapping) {
169+
this.pathMappedEndpoints = new PathMappedEndpoints(BASE_PATH, handlerMapping::getAllEndpoints);
170+
}
171+
164172
@Override
165173
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
166174
if (bean instanceof WebFilterChainProxy webFilterChainProxy) {
167-
return postProcess(webFilterChainProxy);
175+
return postProcess(webFilterChainProxy, this.pathMappedEndpoints);
168176
}
169177
return bean;
170178
}
171179

172-
private WebFilterChainProxy postProcess(WebFilterChainProxy existing) {
180+
private WebFilterChainProxy postProcess(WebFilterChainProxy existing, PathMappedEndpoints pathMappedEndpoints) {
181+
List<String> paths = getPaths(pathMappedEndpoints);
173182
ServerWebExchangeMatcher cloudFoundryRequestMatcher = ServerWebExchangeMatchers
174-
.pathMatchers("/cloudfoundryapplication/**");
183+
.pathMatchers(paths.toArray(new String[] {}));
175184
WebFilter noOpFilter = (exchange, chain) -> chain.filter(exchange);
176185
MatcherSecurityWebFilterChain ignoredRequestFilterChain = new MatcherSecurityWebFilterChain(
177186
cloudFoundryRequestMatcher, Collections.singletonList(noOpFilter));
@@ -180,6 +189,14 @@ private WebFilterChainProxy postProcess(WebFilterChainProxy existing) {
180189
return new WebFilterChainProxy(ignoredRequestFilterChain, allRequestsFilterChain);
181190
}
182191

192+
private static List<String> getPaths(PathMappedEndpoints pathMappedEndpoints) {
193+
List<String> paths = new ArrayList<>();
194+
pathMappedEndpoints.getAllPaths().forEach((path) -> paths.add(path + "/**"));
195+
paths.add(BASE_PATH);
196+
paths.add(BASE_PATH + "/");
197+
return paths;
198+
}
199+
183200
}
184201

185202
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfiguration.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@
3030
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
3131
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
3232
import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper;
33-
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
3433
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
3534
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
3635
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
36+
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
3737
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
3838
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
3939
import org.springframework.boot.actuate.health.HealthEndpoint;
@@ -65,6 +65,9 @@
6565
import org.springframework.security.config.annotation.web.builders.WebSecurity;
6666
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
6767
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
68+
import org.springframework.security.web.util.matcher.OrRequestMatcher;
69+
import org.springframework.security.web.util.matcher.RequestMatcher;
70+
import org.springframework.util.CollectionUtils;
6871
import org.springframework.web.cors.CorsConfiguration;
6972
import org.springframework.web.servlet.DispatcherServlet;
7073

@@ -84,6 +87,8 @@
8487
@ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY)
8588
public class CloudFoundryActuatorAutoConfiguration {
8689

90+
private static final String BASE_PATH = "/cloudfoundryapplication";
91+
8792
@Bean
8893
@ConditionalOnMissingBean
8994
@ConditionalOnAvailableEndpoint
@@ -121,8 +126,7 @@ public CloudFoundryWebEndpointServletHandlerMapping cloudFoundryWebEndpointServl
121126
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
122127
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
123128
return new CloudFoundryWebEndpointServletHandlerMapping(new EndpointMapping("/cloudfoundryapplication"),
124-
webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor,
125-
new EndpointLinksResolver(allEndpoints));
129+
webEndpoints, endpointMediaTypes, getCorsConfiguration(), securityInterceptor, allEndpoints);
126130
}
127131

128132
private CloudFoundrySecurityInterceptor getSecurityInterceptor(RestTemplateBuilder restTemplateBuilder,
@@ -162,18 +166,32 @@ private CorsConfiguration getCorsConfiguration() {
162166
public static class IgnoredCloudFoundryPathsWebSecurityConfiguration {
163167

164168
@Bean
165-
IgnoredCloudFoundryPathsWebSecurityCustomizer ignoreCloudFoundryPathsWebSecurityCustomizer() {
166-
return new IgnoredCloudFoundryPathsWebSecurityCustomizer();
169+
IgnoredCloudFoundryPathsWebSecurityCustomizer ignoreCloudFoundryPathsWebSecurityCustomizer(
170+
CloudFoundryWebEndpointServletHandlerMapping handlerMapping) {
171+
return new IgnoredCloudFoundryPathsWebSecurityCustomizer(handlerMapping);
167172
}
168173

169174
}
170175

171176
@Order(SecurityProperties.IGNORED_ORDER)
172177
static class IgnoredCloudFoundryPathsWebSecurityCustomizer implements WebSecurityCustomizer {
173178

179+
private final PathMappedEndpoints pathMappedEndpoints;
180+
181+
IgnoredCloudFoundryPathsWebSecurityCustomizer(CloudFoundryWebEndpointServletHandlerMapping handlerMapping) {
182+
this.pathMappedEndpoints = new PathMappedEndpoints(BASE_PATH, handlerMapping::getAllEndpoints);
183+
}
184+
174185
@Override
175186
public void customize(WebSecurity web) {
176-
web.ignoring().requestMatchers(new AntPathRequestMatcher("/cloudfoundryapplication/**"));
187+
List<RequestMatcher> requestMatchers = new ArrayList<>();
188+
this.pathMappedEndpoints.getAllPaths()
189+
.forEach((path) -> requestMatchers.add(new AntPathRequestMatcher(path + "/**")));
190+
requestMatchers.add(new AntPathRequestMatcher(BASE_PATH));
191+
requestMatchers.add(new AntPathRequestMatcher(BASE_PATH + "/"));
192+
if (!CollectionUtils.isEmpty(requestMatchers)) {
193+
web.ignoring().requestMatchers(new OrRequestMatcher(requestMatchers));
194+
}
177195
}
178196

179197
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
3737
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryWebEndpointServletHandlerMappingRuntimeHints;
3838
import org.springframework.boot.actuate.endpoint.EndpointId;
39+
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
3940
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
4041
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
4142
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
@@ -67,13 +68,16 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin
6768

6869
private final EndpointLinksResolver linksResolver;
6970

71+
private final Collection<ExposableEndpoint<?>> allEndpoints;
72+
7073
CloudFoundryWebEndpointServletHandlerMapping(EndpointMapping endpointMapping,
7174
Collection<ExposableWebEndpoint> endpoints, EndpointMediaTypes endpointMediaTypes,
7275
CorsConfiguration corsConfiguration, CloudFoundrySecurityInterceptor securityInterceptor,
73-
EndpointLinksResolver linksResolver) {
76+
Collection<ExposableEndpoint<?>> allEndpoints) {
7477
super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, true);
7578
this.securityInterceptor = securityInterceptor;
76-
this.linksResolver = linksResolver;
79+
this.linksResolver = new EndpointLinksResolver(allEndpoints);
80+
this.allEndpoints = allEndpoints;
7781
}
7882

7983
@Override
@@ -87,6 +91,10 @@ protected LinksHandler getLinksHandler() {
8791
return new CloudFoundryLinksHandler();
8892
}
8993

94+
Collection<ExposableEndpoint<?>> getAllEndpoints() {
95+
return this.allEndpoints;
96+
}
97+
9098
class CloudFoundryLinksHandler implements LinksHandler {
9199

92100
@Override

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive;
1818

1919
import java.time.Duration;
20+
import java.util.ArrayList;
2021
import java.util.Arrays;
2122
import java.util.Base64;
23+
import java.util.Collection;
2224
import java.util.Collections;
25+
import java.util.List;
2326
import java.util.Map;
2427
import java.util.function.Consumer;
2528

@@ -29,15 +32,16 @@
2932
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel;
3033
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException;
3134
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryAuthorizationException.Reason;
35+
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
3236
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
3337
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
3438
import org.springframework.boot.actuate.endpoint.annotation.Selector;
3539
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
3640
import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper;
3741
import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper;
38-
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
3942
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
4043
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
44+
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
4145
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
4246
import org.springframework.boot.autoconfigure.AutoConfigurations;
4347
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
@@ -245,9 +249,10 @@ CloudFoundryWebFluxEndpointHandlerMapping cloudFoundryWebEndpointServletHandlerM
245249
CorsConfiguration corsConfiguration = new CorsConfiguration();
246250
corsConfiguration.setAllowedOrigins(Arrays.asList("https://example.com"));
247251
corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST"));
248-
return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping("/cfApplication"),
249-
webEndpointDiscoverer.getEndpoints(), endpointMediaTypes, corsConfiguration, interceptor,
250-
new EndpointLinksResolver(webEndpointDiscoverer.getEndpoints()));
252+
Collection<ExposableWebEndpoint> webEndpoints = webEndpointDiscoverer.getEndpoints();
253+
List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>(webEndpoints);
254+
return new CloudFoundryWebFluxEndpointHandlerMapping(new EndpointMapping("/cfApplication"), webEndpoints,
255+
endpointMediaTypes, corsConfiguration, interceptor, allEndpoints);
251256
}
252257

253258
@Bean

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class ReactiveCloudFoundryActuatorAutoConfigurationTests {
9494
InfoContributorAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
9595
ProjectInfoAutoConfiguration.class, ReactiveCloudFoundryActuatorAutoConfiguration.class));
9696

97+
private static final String BASE_PATH = "/cloudfoundryapplication";
98+
9799
@AfterEach
98100
void close() {
99101
HttpResources.reset();
@@ -175,21 +177,24 @@ void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() {
175177
@Test
176178
@SuppressWarnings("unchecked")
177179
void cloudFoundryPathsIgnoredBySpringSecurity() {
178-
this.contextRunner
180+
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new)
179181
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
180182
"vcap.application.cf_api:https://my-cloud-controller.com")
181183
.run((context) -> {
182184
WebFilterChainProxy chainProxy = context.getBean(WebFilterChainProxy.class);
183185
List<SecurityWebFilterChain> filters = (List<SecurityWebFilterChain>) ReflectionTestUtils
184186
.getField(chainProxy, "filters");
185-
Boolean cfRequestMatches = filters.get(0)
186-
.matches(MockServerWebExchange
187-
.from(MockServerHttpRequest.get("/cloudfoundryapplication/my-path").build()))
188-
.block(Duration.ofSeconds(30));
189-
Boolean otherRequestMatches = filters.get(0)
190-
.matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build()))
191-
.block(Duration.ofSeconds(30));
187+
Boolean cfBaseRequestMatches = getMatches(filters, BASE_PATH);
188+
Boolean cfBaseWithTrailingSlashRequestMatches = getMatches(filters, BASE_PATH + "/");
189+
Boolean cfRequestMatches = getMatches(filters, BASE_PATH + "/test");
190+
Boolean cfRequestWithAdditionalPathMatches = getMatches(filters, BASE_PATH + "/test/a");
191+
Boolean otherCfRequestMatches = getMatches(filters, BASE_PATH + "/other-path");
192+
Boolean otherRequestMatches = getMatches(filters, "/some-other-path");
193+
assertThat(cfBaseRequestMatches).isTrue();
194+
assertThat(cfBaseWithTrailingSlashRequestMatches).isTrue();
192195
assertThat(cfRequestMatches).isTrue();
196+
assertThat(cfRequestWithAdditionalPathMatches).isTrue();
197+
assertThat(otherCfRequestMatches).isFalse();
193198
assertThat(otherRequestMatches).isFalse();
194199
otherRequestMatches = filters.get(1)
195200
.matches(MockServerWebExchange.from(MockServerHttpRequest.get("/some-other-path").build()))
@@ -199,6 +204,13 @@ void cloudFoundryPathsIgnoredBySpringSecurity() {
199204

200205
}
201206

207+
private static Boolean getMatches(List<SecurityWebFilterChain> filters, String urlTemplate) {
208+
Boolean cfBaseRequestMatches = filters.get(0)
209+
.matches(MockServerWebExchange.from(MockServerHttpRequest.get(urlTemplate).build()))
210+
.block(Duration.ofSeconds(30));
211+
return cfBaseRequestMatches;
212+
}
213+
202214
@Test
203215
void cloudFoundryPlatformInactive() {
204216
this.contextRunner

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ class CloudFoundryActuatorAutoConfigurationTests {
7777
ServletManagementContextAutoConfiguration.class, EndpointAutoConfiguration.class,
7878
WebEndpointAutoConfiguration.class, CloudFoundryActuatorAutoConfiguration.class));
7979

80+
private static String BASE_PATH = "/cloudfoundryapplication";
81+
8082
@Test
8183
void cloudFoundryPlatformActive() {
8284
this.contextRunner
@@ -168,20 +170,31 @@ void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() {
168170

169171
@Test
170172
void cloudFoundryPathsIgnoredBySpringSecurity() {
171-
this.contextRunner.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
173+
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new)
174+
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
172175
.run((context) -> {
173176
FilterChainProxy securityFilterChain = (FilterChainProxy) context
174177
.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN);
175178
SecurityFilterChain chain = securityFilterChain.getFilterChains().get(0);
176-
MockHttpServletRequest request = new MockHttpServletRequest();
177-
request.setServletPath("/cloudfoundryapplication/my-path");
178179
assertThat(chain.getFilters()).isEmpty();
179-
assertThat(chain.matches(request)).isTrue();
180+
MockHttpServletRequest request = new MockHttpServletRequest();
181+
testCloudFoundrySecurity(request, BASE_PATH, chain);
182+
testCloudFoundrySecurity(request, BASE_PATH + "/", chain);
183+
testCloudFoundrySecurity(request, BASE_PATH + "/test", chain);
184+
testCloudFoundrySecurity(request, BASE_PATH + "/test/a", chain);
185+
request.setServletPath(BASE_PATH + "/other-path");
186+
assertThat(chain.matches(request)).isFalse();
180187
request.setServletPath("/some-other-path");
181188
assertThat(chain.matches(request)).isFalse();
182189
});
183190
}
184191

192+
private static void testCloudFoundrySecurity(MockHttpServletRequest request, String basePath,
193+
SecurityFilterChain chain) {
194+
request.setServletPath(basePath);
195+
assertThat(chain.matches(request)).isTrue();
196+
}
197+
185198
@Test
186199
void cloudFoundryPlatformInactive() {
187200
this.contextRunner.withPropertyValues()

0 commit comments

Comments
 (0)