Skip to content

Commit 82f89b4

Browse files
committed
Add custom headers to allowed CORS headers for CF actuators
Update CORS configuration to support Authorization and X-Cf-App-Instance. See gh-7108
1 parent 3018e95 commit 82f89b4

File tree

4 files changed

+25
-4
lines changed

4 files changed

+25
-4
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ private CorsConfiguration getCorsConfiguration() {
9090
corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
9191
corsConfiguration.setAllowedMethods(
9292
Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
93+
corsConfiguration
94+
.setAllowedHeaders(Arrays.asList("Authorization", "X-Cf-App-Instance"));
9395
return corsConfiguration;
9496
}
9597

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundrySecurityInterceptor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.boot.actuate.cloudfoundry.CloudFoundryAuthorizationException.Reason;
2626
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
2727
import org.springframework.util.StringUtils;
28+
import org.springframework.web.cors.CorsUtils;
2829
import org.springframework.web.method.HandlerMethod;
2930
import org.springframework.web.servlet.HandlerInterceptor;
3031
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@@ -55,6 +56,9 @@ class CloudFoundrySecurityInterceptor extends HandlerInterceptorAdapter {
5556
@Override
5657
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
5758
Object o) throws Exception {
59+
if (CorsUtils.isPreFlightRequest(request)) {
60+
return true;
61+
}
5862
try {
5963
if (!StringUtils.hasText(this.applicationId)) {
6064
throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.boot.actuate.cloudfoundry;
1818

19+
import java.util.Arrays;
20+
1921
import org.junit.After;
2022
import org.junit.Before;
2123
import org.junit.Test;
@@ -75,18 +77,20 @@ public void close() {
7577

7678
@Test
7779
public void cloudFoundryPlatformActive() throws Exception {
78-
CloudFoundryEndpointHandlerMapping handlerMapping = x();
80+
CloudFoundryEndpointHandlerMapping handlerMapping = getHandlerMapping();
7981
assertThat(handlerMapping.getPrefix()).isEqualTo("/cloudfoundryapplication");
8082
CorsConfiguration corsConfiguration = (CorsConfiguration) ReflectionTestUtils
8183
.getField(handlerMapping, "corsConfiguration");
8284
assertThat(corsConfiguration.getAllowedOrigins()).contains("*");
8385
assertThat(corsConfiguration.getAllowedMethods()).contains(HttpMethod.GET.name(),
8486
HttpMethod.POST.name());
87+
assertThat(corsConfiguration.getAllowedHeaders()
88+
.containsAll(Arrays.asList("Authorization", "X-Cf-App-Instance")));
8589
}
8690

8791
@Test
8892
public void cloudFoundryPlatformActiveSetsApplicationId() throws Exception {
89-
CloudFoundryEndpointHandlerMapping handlerMapping = x();
93+
CloudFoundryEndpointHandlerMapping handlerMapping = getHandlerMapping();
9094
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
9195
"securityInterceptor");
9296
String applicationId = (String) ReflectionTestUtils.getField(interceptor,
@@ -96,7 +100,7 @@ public void cloudFoundryPlatformActiveSetsApplicationId() throws Exception {
96100

97101
@Test
98102
public void cloudFoundryPlatformActiveSetsCloudControllerUrl() throws Exception {
99-
CloudFoundryEndpointHandlerMapping handlerMapping = x();
103+
CloudFoundryEndpointHandlerMapping handlerMapping = getHandlerMapping();
100104
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
101105
"securityInterceptor");
102106
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
@@ -123,7 +127,7 @@ public void cloudFoundryPlatformActiveAndCloudControllerUrlNotPresent()
123127
assertThat(interceptorSecurityService).isNull();
124128
}
125129

126-
private CloudFoundryEndpointHandlerMapping x() {
130+
private CloudFoundryEndpointHandlerMapping getHandlerMapping() {
127131
EnvironmentTestUtils.addEnvironment(this.context, "VCAP_APPLICATION:---",
128132
"vcap.application.application_id:my-app-id",
129133
"vcap.application.cf_api:http://my-cloud-controller.com");

spring-boot-actuator/src/test/java/org/springframework/boot/actuate/cloudfoundry/CloudFoundrySecurityInterceptorTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.boot.actuate.cloudfoundry.CloudFoundryAuthorizationException.Reason;
2727
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
2828
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
29+
import org.springframework.http.HttpHeaders;
2930
import org.springframework.http.HttpStatus;
3031
import org.springframework.mock.web.MockHttpServletRequest;
3132
import org.springframework.mock.web.MockHttpServletResponse;
@@ -69,6 +70,16 @@ public void setup() throws Exception {
6970
this.response = new MockHttpServletResponse();
7071
}
7172

73+
@Test
74+
public void preHandleWhenRequestIsPreFlightShouldReturnTrue() throws Exception {
75+
this.request.setMethod("OPTIONS");
76+
this.request.addHeader(HttpHeaders.ORIGIN, "http://example.com");
77+
this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
78+
boolean preHandle = this.interceptor.preHandle(this.request, this.response,
79+
this.handlerMethod);
80+
assertThat(preHandle).isTrue();
81+
}
82+
7283
@Test
7384
public void preHandleWhenTokenIsMissingShouldReturnFalse() throws Exception {
7485
boolean preHandle = this.interceptor.preHandle(this.request, this.response,

0 commit comments

Comments
 (0)