Skip to content

Commit 8d9e8c4

Browse files
committed
Merge branch 'main' into 4.0.x
Closes gh-45856
2 parents c981d0a + 564b65b commit 8d9e8c4

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ public static class IgnoredCloudFoundryPathsWebSecurityConfiguration {
174174
SecurityFilterChain cloudFoundrySecurityFilterChain(HttpSecurity http,
175175
CloudFoundryWebEndpointServletHandlerMapping handlerMapping) throws Exception {
176176
RequestMatcher cloudFoundryRequest = getRequestMatcher(handlerMapping);
177+
http.csrf((csrf) -> csrf.ignoringRequestMatchers(cloudFoundryRequest));
177178
http.securityMatchers((matches) -> matches.requestMatchers(cloudFoundryRequest))
178179
.authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll());
179180
return http.build();

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.boot.actuate.endpoint.EndpointId;
3434
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
3535
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
36+
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
3637
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
3738
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
3839
import org.springframework.boot.actuate.endpoint.web.WebOperation;
@@ -49,17 +50,24 @@
4950
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
5051
import org.springframework.context.ApplicationContext;
5152
import org.springframework.http.HttpMethod;
53+
import org.springframework.http.MediaType;
5254
import org.springframework.mock.web.MockHttpServletRequest;
5355
import org.springframework.security.config.BeanIds;
5456
import org.springframework.security.web.FilterChainProxy;
5557
import org.springframework.security.web.SecurityFilterChain;
5658
import org.springframework.test.util.ReflectionTestUtils;
59+
import org.springframework.test.web.servlet.MockMvc;
5760
import org.springframework.test.web.servlet.assertj.MockMvcTester;
61+
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
5862
import org.springframework.web.client.RestTemplate;
5963
import org.springframework.web.cors.CorsConfiguration;
6064
import org.springframework.web.filter.CompositeFilter;
6165

6266
import static org.assertj.core.api.Assertions.assertThat;
67+
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
68+
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
69+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
70+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
6371

6472
/**
6573
* Tests for {@link CloudFoundryActuatorAutoConfiguration}.
@@ -170,7 +178,7 @@ void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent() {
170178
}
171179

172180
@Test
173-
void cloudFoundryPathsIgnoredBySpringSecurity() {
181+
void cloudFoundryPathsPermittedBySpringSecurity() {
174182
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new)
175183
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
176184
.run((context) -> {
@@ -189,6 +197,19 @@ void cloudFoundryPathsIgnoredBySpringSecurity() {
189197
});
190198
}
191199

200+
@Test
201+
void cloudFoundryPathsPermittedWithCsrfBySpringSecurity() {
202+
this.contextRunner.withBean(TestEndpoint.class, TestEndpoint::new)
203+
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id")
204+
.run((context) -> {
205+
MockMvc mvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
206+
mvc.perform(post(BASE_PATH + "/test?name=test").contentType(MediaType.APPLICATION_JSON)
207+
.with(csrf().useInvalidToken())).andExpect(status().isServiceUnavailable());
208+
// If CSRF fails we'll get a 403, if it works we get service unavailable
209+
// because of "Cloud controller URL is not available"
210+
});
211+
}
212+
192213
private SecurityFilterChain getSecurityFilterChain(AssertableWebApplicationContext context) {
193214
Filter springSecurityFilterChain = context.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN, Filter.class);
194215
FilterChainProxy filterChainProxy = getFilterChainProxy(springSecurityFilterChain);
@@ -258,7 +279,7 @@ void endpointPathCustomizationIsNotApplied() {
258279
.findFirst()
259280
.get();
260281
Collection<WebOperation> operations = endpoint.getOperations();
261-
assertThat(operations).hasSize(1);
282+
assertThat(operations).hasSize(2);
262283
assertThat(operations.iterator().next().getRequestPredicate().getPath()).isEqualTo("test");
263284
});
264285
}
@@ -307,6 +328,10 @@ String hello() {
307328
return "hello world";
308329
}
309330

331+
@WriteOperation
332+
void update(String name) {
333+
}
334+
310335
}
311336

312337
}

0 commit comments

Comments
 (0)