Support custom CorsConfigurationSource in AbstractHandlerMapping

This commit allows to specify a custom CorsConfigurationSource
in AbstractHandlerMapping (both Servlet and Reactive variants).

AbstractHandlerMapping#getCorsConfigurations method is now
deprecated.

Issue: SPR-17067
This commit is contained in:
Sebastien Deleuze
2018-08-08 09:25:23 +02:00
parent b325c74216
commit 7e9b7102b7
5 changed files with 167 additions and 26 deletions

View File

@@ -85,6 +85,7 @@ import org.springframework.web.context.request.async.CallableProcessingIntercept
import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.CompositeUriComponentsContributor;
import org.springframework.web.method.support.InvocableHandlerMethod;
@@ -887,7 +888,9 @@ public class MvcNamespaceTests {
for (String beanName : beanNames) {
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping)appContext.getBean(beanName);
assertNotNull(handlerMapping);
Map<String, CorsConfiguration> configs = handlerMapping.getCorsConfigurations();
DirectFieldAccessor accessor = new DirectFieldAccessor(handlerMapping);
Map<String, CorsConfiguration> configs = ((UrlBasedCorsConfigurationSource)accessor
.getPropertyValue("corsConfigurationSource")).getCorsConfigurations();
assertNotNull(configs);
assertEquals(1, configs.size());
CorsConfiguration config = configs.get("/**");
@@ -910,7 +913,9 @@ public class MvcNamespaceTests {
for (String beanName : beanNames) {
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping)appContext.getBean(beanName);
assertNotNull(handlerMapping);
Map<String, CorsConfiguration> configs = handlerMapping.getCorsConfigurations();
DirectFieldAccessor accessor = new DirectFieldAccessor(handlerMapping);
Map<String, CorsConfiguration> configs = ((UrlBasedCorsConfigurationSource)accessor
.getPropertyValue("corsConfigurationSource")).getCorsConfigurations();
assertNotNull(configs);
assertEquals(2, configs.size());
CorsConfiguration config = configs.get("/api/**");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -149,6 +149,39 @@ public class CorsAbstractHandlerMappingTests {
assertArrayEquals(config.getAllowedOrigins().toArray(), new String[]{"*"});
}
@Test
public void actualRequestWithCorsConfigurationSource() throws Exception {
this.handlerMapping.setCorsConfigurationSource(new CustomCorsConfigurationSource());
this.request.setMethod(RequestMethod.GET.name());
this.request.setRequestURI("/foo");
this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com");
this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
HandlerExecutionChain chain = handlerMapping.getHandler(this.request);
assertNotNull(chain);
assertTrue(chain.getHandler() instanceof SimpleHandler);
CorsConfiguration config = getCorsConfiguration(chain, false);
assertNotNull(config);
assertArrayEquals(new String[]{"*"}, config.getAllowedOrigins().toArray());
assertEquals(true, config.getAllowCredentials());
}
@Test
public void preflightRequestWithCorsConfigurationSource() throws Exception {
this.handlerMapping.setCorsConfigurationSource(new CustomCorsConfigurationSource());
this.request.setMethod(RequestMethod.OPTIONS.name());
this.request.setRequestURI("/foo");
this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com");
this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
HandlerExecutionChain chain = handlerMapping.getHandler(this.request);
assertNotNull(chain);
assertNotNull(chain.getHandler());
assertTrue(chain.getHandler().getClass().getSimpleName().equals("PreFlightHandler"));
CorsConfiguration config = getCorsConfiguration(chain, true);
assertNotNull(config);
assertArrayEquals(new String[]{"*"}, config.getAllowedOrigins().toArray());
assertEquals(true, config.getAllowCredentials());
}
private CorsConfiguration getCorsConfiguration(HandlerExecutionChain chain, boolean isPreFlightRequest) {
if (isPreFlightRequest) {
@@ -208,4 +241,15 @@ public class CorsAbstractHandlerMappingTests {
}
public class CustomCorsConfigurationSource implements CorsConfigurationSource {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
return config;
}
}
}