Add global CORS configuration capabilities
This commit adds JavaConfig based global CORS configuration capabilities to Spring MVC. It is now possible to specify multiple CORS configurations, each mapped on a path pattern, by overriding WebMvcConfigurerAdapter#configureCrossOrigin(CrossOriginConfigurer). It is also possible to combine global and @CrossOrigin based CORS configuration. Issue: SPR-12933
This commit is contained in:
@@ -53,6 +53,55 @@ public class CorsConfiguration {
|
||||
public CorsConfiguration() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
public CorsConfiguration(CorsConfiguration other) {
|
||||
this.allowedOrigins = other.allowedOrigins;
|
||||
this.allowedMethods = other.allowedMethods;
|
||||
this.allowedHeaders = other.allowedHeaders;
|
||||
this.exposedHeaders = other.exposedHeaders;
|
||||
this.allowCredentials = other.allowCredentials;
|
||||
this.maxAge = other.maxAge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the specified {@link CorsConfiguration} with this one.
|
||||
* Properties of this configuration are overridden only by non-null properties
|
||||
* of the provided one.
|
||||
* @return the combined {@link CorsConfiguration}
|
||||
*/
|
||||
public CorsConfiguration combine(CorsConfiguration other) {
|
||||
if (other == null) {
|
||||
return this;
|
||||
}
|
||||
CorsConfiguration config = new CorsConfiguration(this);
|
||||
config.setAllowedOrigins(combine(this.getAllowedOrigins(), other.getAllowedOrigins()));
|
||||
config.setAllowedMethods(combine(this.getAllowedMethods(), other.getAllowedMethods()));
|
||||
config.setAllowedHeaders(combine(this.getAllowedHeaders(), other.getAllowedHeaders()));
|
||||
config.setExposedHeaders(combine(this.getExposedHeaders(), other.getExposedHeaders()));
|
||||
Boolean allowCredentials = other.getAllowCredentials();
|
||||
if (allowCredentials != null) {
|
||||
config.setAllowCredentials(allowCredentials);
|
||||
}
|
||||
Long maxAge = other.getMaxAge();
|
||||
if (maxAge != null) {
|
||||
config.setMaxAge(maxAge);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
private List<String> combine(List<String> source, List<String> other) {
|
||||
if (other == null) {
|
||||
return source;
|
||||
}
|
||||
if (source == null || source.contains("*")) {
|
||||
return other;
|
||||
}
|
||||
List<String> combined = new ArrayList<String>(source);
|
||||
combined.addAll(other);
|
||||
return combined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure origins to allow, e.g. "http://domain1.com". The special value
|
||||
@@ -142,6 +191,9 @@ public class CorsConfiguration {
|
||||
* <p>By default this is not set.
|
||||
*/
|
||||
public void setExposedHeaders(List<String> exposedHeaders) {
|
||||
if (exposedHeaders != null && exposedHeaders.contains("*")) {
|
||||
throw new IllegalArgumentException("'*' is not a valid exposed header value");
|
||||
}
|
||||
this.exposedHeaders = exposedHeaders;
|
||||
}
|
||||
|
||||
@@ -149,6 +201,9 @@ public class CorsConfiguration {
|
||||
* Add a single response header to expose.
|
||||
*/
|
||||
public void addExposedHeader(String exposedHeader) {
|
||||
if ("*".equals(exposedHeader)) {
|
||||
throw new IllegalArgumentException("'*' is not a valid exposed header value");
|
||||
}
|
||||
if (this.exposedHeaders == null) {
|
||||
this.exposedHeaders = new ArrayList<String>();
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -40,6 +39,115 @@ public class CorsConfigurationTests {
|
||||
public void setup() {
|
||||
config = new CorsConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setNullValues() {
|
||||
config.setAllowedOrigins(null);
|
||||
assertNull(config.getAllowedOrigins());
|
||||
config.setAllowedHeaders(null);
|
||||
assertNull(config.getAllowedHeaders());
|
||||
config.setAllowedMethods(null);
|
||||
assertNull(config.getAllowedMethods());
|
||||
config.setExposedHeaders(null);
|
||||
assertNull(config.getExposedHeaders());
|
||||
config.setAllowCredentials(null);
|
||||
assertNull(config.getAllowCredentials());
|
||||
config.setMaxAge(null);
|
||||
assertNull(config.getMaxAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setValues() {
|
||||
config.addAllowedOrigin("*");
|
||||
assertEquals(Arrays.asList("*"), config.getAllowedOrigins());
|
||||
config.addAllowedHeader("*");
|
||||
assertEquals(Arrays.asList("*"), config.getAllowedHeaders());
|
||||
config.addAllowedMethod("*");
|
||||
assertEquals(Arrays.asList("*"), config.getAllowedMethods());
|
||||
config.addExposedHeader("header1");
|
||||
config.addExposedHeader("header2");
|
||||
assertEquals(Arrays.asList("header1", "header2"), config.getExposedHeaders());
|
||||
config.setAllowCredentials(true);
|
||||
assertTrue(config.getAllowCredentials());
|
||||
config.setMaxAge(123L);
|
||||
assertEquals(new Long(123), config.getMaxAge());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void asteriskWildCardOnAddExposedHeader() {
|
||||
config.addExposedHeader("*");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void asteriskWildCardOnSetExposedHeaders() {
|
||||
config.setExposedHeaders(Arrays.asList("*"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combineWithNull() {
|
||||
config.setAllowedOrigins(Arrays.asList("*"));
|
||||
config.combine(null);
|
||||
assertEquals(Arrays.asList("*"), config.getAllowedOrigins());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combineWithNullProperties() {
|
||||
config.addAllowedOrigin("*");
|
||||
config.addAllowedHeader("header1");
|
||||
config.addExposedHeader("header3");
|
||||
config.addAllowedMethod(HttpMethod.GET.name());
|
||||
config.setMaxAge(123L);
|
||||
config.setAllowCredentials(true);
|
||||
CorsConfiguration other = new CorsConfiguration();
|
||||
config = config.combine(other);
|
||||
assertEquals(Arrays.asList("*"), config.getAllowedOrigins());
|
||||
assertEquals(Arrays.asList("header1"), config.getAllowedHeaders());
|
||||
assertEquals(Arrays.asList("header3"), config.getExposedHeaders());
|
||||
assertEquals(Arrays.asList(HttpMethod.GET.name()), config.getAllowedMethods());
|
||||
assertEquals(new Long(123), config.getMaxAge());
|
||||
assertTrue(config.getAllowCredentials());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combineWithAsteriskWildCard() {
|
||||
config.addAllowedOrigin("*");
|
||||
config.addAllowedHeader("*");
|
||||
config.addAllowedMethod("*");
|
||||
CorsConfiguration other = new CorsConfiguration();
|
||||
other.addAllowedOrigin("http://domain.com");
|
||||
other.addAllowedHeader("header1");
|
||||
other.addExposedHeader("header2");
|
||||
other.addAllowedMethod(HttpMethod.PUT.name());
|
||||
config = config.combine(other);
|
||||
assertEquals(Arrays.asList("http://domain.com"), config.getAllowedOrigins());
|
||||
assertEquals(Arrays.asList("header1"), config.getAllowedHeaders());
|
||||
assertEquals(Arrays.asList("header2"), config.getExposedHeaders());
|
||||
assertEquals(Arrays.asList(HttpMethod.PUT.name()), config.getAllowedMethods());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combine() {
|
||||
config.addAllowedOrigin("http://domain1.com");
|
||||
config.addAllowedHeader("header1");
|
||||
config.addExposedHeader("header3");
|
||||
config.addAllowedMethod(HttpMethod.GET.name());
|
||||
config.setMaxAge(123L);
|
||||
config.setAllowCredentials(true);
|
||||
CorsConfiguration other = new CorsConfiguration();
|
||||
other.addAllowedOrigin("http://domain2.com");
|
||||
other.addAllowedHeader("header2");
|
||||
other.addExposedHeader("header4");
|
||||
other.addAllowedMethod(HttpMethod.PUT.name());
|
||||
other.setMaxAge(456L);
|
||||
other.setAllowCredentials(false);
|
||||
config = config.combine(other);
|
||||
assertEquals(Arrays.asList("http://domain1.com", "http://domain2.com"), config.getAllowedOrigins());
|
||||
assertEquals(Arrays.asList("header1", "header2"), config.getAllowedHeaders());
|
||||
assertEquals(Arrays.asList("header3", "header4"), config.getExposedHeaders());
|
||||
assertEquals(Arrays.asList(HttpMethod.GET.name(), HttpMethod.PUT.name()), config.getAllowedMethods());
|
||||
assertEquals(new Long(456), config.getMaxAge());
|
||||
assertFalse(config.getAllowCredentials());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkOriginAllowed() {
|
||||
|
||||
Reference in New Issue
Block a user