From 0f8a819af91025c99873b9071f65b54728eac120 Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Thu, 13 Jul 2017 14:17:44 -0700 Subject: [PATCH] Enable cors in default management security config Fixes gh-9548 --- ...anagementWebSecurityAutoConfiguration.java | 2 +- .../spring-boot-sample-actuator/pom.xml | 5 ++ .../CorsSampleActuatorApplicationTests.java | 88 +++++++++++++++++++ .../resources/application-cors.properties | 2 + 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/CorsSampleActuatorApplicationTests.java create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-cors.properties diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java index 7eac112ff73..4467e687c9c 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java @@ -222,7 +222,7 @@ public class ManagementWebSecurityAutoConfiguration { http.requestMatcher(matcher); // ... but permitAll() for the non-sensitive ones configurePermittedRequests(http.authorizeRequests()); - http.httpBasic().authenticationEntryPoint(entryPoint); + http.httpBasic().authenticationEntryPoint(entryPoint).and().cors(); // No cookies for management endpoints by default http.csrf().disable(); http.sessionManagement() diff --git a/spring-boot-samples/spring-boot-sample-actuator/pom.xml b/spring-boot-samples/spring-boot-sample-actuator/pom.xml index 287a2a277c2..cba429d09f6 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/pom.xml +++ b/spring-boot-samples/spring-boot-sample-actuator/pom.xml @@ -41,6 +41,11 @@ spring-boot-starter-remote-shell + + org.apache.httpcomponents + httpclient + runtime + com.h2database h2 diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/CorsSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/CorsSampleActuatorApplicationTests.java new file mode 100644 index 00000000000..dffe86f1772 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/CorsSampleActuatorApplicationTests.java @@ -0,0 +1,88 @@ +package sample.actuator; + +import java.net.URI; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.LocalHostUriTemplateHandler; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ApplicationContext; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for cors preflight requests to management endpoints. + * + * @author Madhura Bhave + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@DirtiesContext +@ActiveProfiles("cors") +public class CorsSampleActuatorApplicationTests { + + private TestRestTemplate testRestTemplate; + + @Autowired + ApplicationContext applicationContext; + + @Before + public void setUp() throws Exception { + RestTemplate restTemplate = new RestTemplate(); + LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler( + this.applicationContext.getEnvironment(), "http"); + restTemplate.setUriTemplateHandler(handler); + restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory()); + this.testRestTemplate = new TestRestTemplate(restTemplate); + } + + @Test + public void sensitiveEndpointShouldReturnUnauthorized() throws Exception { + ResponseEntity entity = this.testRestTemplate.getForEntity("/env", Map.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); + } + + @Test + public void preflightRequestForInsensitiveShouldReturnOk() throws Exception { + RequestEntity healthRequest = RequestEntity.options(new URI("/health")) + .header("Origin","http://localhost:8080") + .header("Access-Control-Request-Method", "GET") + .build(); + ResponseEntity exchange = this.testRestTemplate.exchange(healthRequest, Map.class); + assertThat(exchange.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + public void preflightRequestForSensitiveEndpointShouldReturnOk() throws Exception { + RequestEntity entity = RequestEntity.options(new URI("/env")) + .header("Origin","http://localhost:8080") + .header("Access-Control-Request-Method", "GET") + .build(); + ResponseEntity env = this.testRestTemplate.exchange(entity, Map.class); + assertThat(env.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + public void preflightRequestWhenCorsConfigInvalidShouldReturnForbidden() throws Exception { + RequestEntity entity = RequestEntity.options(new URI("/health")) + .header("Origin","http://localhost:9095") + .header("Access-Control-Request-Method", "GET") + .build(); + ResponseEntity exchange = this.testRestTemplate.exchange(entity, byte[].class); + assertThat(exchange.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-cors.properties b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-cors.properties new file mode 100644 index 00000000000..2bfb6b6cdbd --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-cors.properties @@ -0,0 +1,2 @@ +endpoints.cors.allowed-origins=http://localhost:8080 +endpoints.cors.allowed-methods=GET \ No newline at end of file