Add custom headers to allowed CORS headers for CF actuators

Update CORS configuration to support Authorization and X-Cf-App-Instance.

See gh-7108
This commit is contained in:
Madhura Bhave 2016-11-07 15:12:43 -08:00
parent 3018e95261
commit 82f89b4ac1
4 changed files with 25 additions and 4 deletions

View File

@ -90,6 +90,8 @@ public class CloudFoundryActuatorAutoConfiguration {
corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL);
corsConfiguration.setAllowedMethods(
Arrays.asList(HttpMethod.GET.name(), HttpMethod.POST.name()));
corsConfiguration
.setAllowedHeaders(Arrays.asList("Authorization", "X-Cf-App-Instance"));
return corsConfiguration;
}

View File

@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.boot.actuate.cloudfoundry.CloudFoundryAuthorizationException.Reason;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@ -55,6 +56,9 @@ class CloudFoundrySecurityInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object o) throws Exception {
if (CorsUtils.isPreFlightRequest(request)) {
return true;
}
try {
if (!StringUtils.hasText(this.applicationId)) {
throw new CloudFoundryAuthorizationException(Reason.SERVICE_UNAVAILABLE,

View File

@ -16,6 +16,8 @@
package org.springframework.boot.actuate.cloudfoundry;
import java.util.Arrays;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -75,18 +77,20 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformActive() throws Exception {
CloudFoundryEndpointHandlerMapping handlerMapping = x();
CloudFoundryEndpointHandlerMapping handlerMapping = getHandlerMapping();
assertThat(handlerMapping.getPrefix()).isEqualTo("/cloudfoundryapplication");
CorsConfiguration corsConfiguration = (CorsConfiguration) ReflectionTestUtils
.getField(handlerMapping, "corsConfiguration");
assertThat(corsConfiguration.getAllowedOrigins()).contains("*");
assertThat(corsConfiguration.getAllowedMethods()).contains(HttpMethod.GET.name(),
HttpMethod.POST.name());
assertThat(corsConfiguration.getAllowedHeaders()
.containsAll(Arrays.asList("Authorization", "X-Cf-App-Instance")));
}
@Test
public void cloudFoundryPlatformActiveSetsApplicationId() throws Exception {
CloudFoundryEndpointHandlerMapping handlerMapping = x();
CloudFoundryEndpointHandlerMapping handlerMapping = getHandlerMapping();
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
String applicationId = (String) ReflectionTestUtils.getField(interceptor,
@ -96,7 +100,7 @@ public class CloudFoundryActuatorAutoConfigurationTests {
@Test
public void cloudFoundryPlatformActiveSetsCloudControllerUrl() throws Exception {
CloudFoundryEndpointHandlerMapping handlerMapping = x();
CloudFoundryEndpointHandlerMapping handlerMapping = getHandlerMapping();
Object interceptor = ReflectionTestUtils.getField(handlerMapping,
"securityInterceptor");
Object interceptorSecurityService = ReflectionTestUtils.getField(interceptor,
@ -123,7 +127,7 @@ public class CloudFoundryActuatorAutoConfigurationTests {
assertThat(interceptorSecurityService).isNull();
}
private CloudFoundryEndpointHandlerMapping x() {
private CloudFoundryEndpointHandlerMapping getHandlerMapping() {
EnvironmentTestUtils.addEnvironment(this.context, "VCAP_APPLICATION:---",
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com");

View File

@ -26,6 +26,7 @@ import org.mockito.MockitoAnnotations;
import org.springframework.boot.actuate.cloudfoundry.CloudFoundryAuthorizationException.Reason;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@ -69,6 +70,16 @@ public class CloudFoundrySecurityInterceptorTests {
this.response = new MockHttpServletResponse();
}
@Test
public void preHandleWhenRequestIsPreFlightShouldReturnTrue() throws Exception {
this.request.setMethod("OPTIONS");
this.request.addHeader(HttpHeaders.ORIGIN, "http://example.com");
this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
boolean preHandle = this.interceptor.preHandle(this.request, this.response,
this.handlerMethod);
assertThat(preHandle).isTrue();
}
@Test
public void preHandleWhenTokenIsMissingShouldReturnFalse() throws Exception {
boolean preHandle = this.interceptor.preHandle(this.request, this.response,