Skip to content

Commit

Permalink
Merge pull request #24680 from pedivo
Browse files Browse the repository at this point in the history
* gh-24680:
  Polish "Add config prop for endpoints' CORS allowed origin patterns"
  Add config prop for endpoints' CORS allowed origin patterns

Closes gh-24680
  • Loading branch information
wilkinsona committed Jan 19, 2021
2 parents 743343c + b095c77 commit 847bb62
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
Expand Down Expand Up @@ -37,11 +37,21 @@
public class CorsEndpointProperties {

/**
* Comma-separated list of origins to allow. '*' allows all origins. When not set,
* CORS support is disabled.
* Comma-separated list of origins to allow. '*' allows all origins. When credentials
* are allowed, '*' cannot be used and origin patterns should be configured instead.
* When no allowed origins or allowed origin patterns are set, CORS support is
* disabled.
*/
private List<String> allowedOrigins = new ArrayList<>();

/**
* Comma-separated list of origin patterns to allow. Unlike allowed origins which only
* supports '*', origin patterns are more flexible (for example
* 'https://*.example.com') and can be used when credentials are allowed. When no
* allowed origin patterns or allowed origins are set, CORS support is disabled.
*/
private List<String> allowedOriginPatterns = new ArrayList<>();

/**
* Comma-separated list of methods to allow. '*' allows all methods. When not set,
* defaults to GET.
Expand Down Expand Up @@ -78,6 +88,14 @@ public void setAllowedOrigins(List<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}

public List<String> getAllowedOriginPatterns() {
return this.allowedOriginPatterns;
}

public void setAllowedOriginPatterns(List<String> allowedOriginPatterns) {
this.allowedOriginPatterns = allowedOriginPatterns;
}

public List<String> getAllowedMethods() {
return this.allowedMethods;
}
Expand Down Expand Up @@ -119,12 +137,13 @@ public void setMaxAge(Duration maxAge) {
}

public CorsConfiguration toCorsConfiguration() {
if (CollectionUtils.isEmpty(this.allowedOrigins)) {
if (CollectionUtils.isEmpty(this.allowedOrigins) && CollectionUtils.isEmpty(this.allowedOriginPatterns)) {
return null;
}
PropertyMapper map = PropertyMapper.get();
CorsConfiguration configuration = new CorsConfiguration();
map.from(this::getAllowedOrigins).to(configuration::setAllowedOrigins);
map.from(this::getAllowedOriginPatterns).to(configuration::setAllowedOriginPatterns);
map.from(this::getAllowedHeaders).whenNot(CollectionUtils::isEmpty).to(configuration::setAllowedHeaders);
map.from(this::getAllowedMethods).whenNot(CollectionUtils::isEmpty).to(configuration::setAllowedMethods);
map.from(this::getExposedHeaders).whenNot(CollectionUtils::isEmpty).to(configuration::setExposedHeaders);
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
Expand Down Expand Up @@ -71,6 +71,19 @@ void settingAllowedOriginsEnablesCors() {
}));
}

@Test
void settingAllowedOriginPatternsEnablesCors() {
this.contextRunner
.withPropertyValues("management.endpoints.web.cors.allowed-origin-patterns:*.example.org",
"management.endpoints.web.cors.allow-credentials:true")
.run(withWebTestClient((webTestClient) -> {
webTestClient.options().uri("/actuator/beans").header("Origin", "spring.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET").exchange().expectStatus()
.isForbidden();
performAcceptedCorsRequest(webTestClient, "/actuator/beans");
}));
}

@Test
void maxAgeDefaultsTo30Minutes() {
this.contextRunner.withPropertyValues("management.endpoints.web.cors.allowed-origins:spring.example.org")
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
Expand Down Expand Up @@ -77,6 +77,17 @@ void settingAllowedOriginsEnablesCors() {
}));
}

@Test
void settingAllowedOriginPatternsEnablesCors() {
this.contextRunner.withPropertyValues("management.endpoints.web.cors.allowed-origin-patterns:*.example.com",
"management.endpoints.web.cors.allow-credentials:true").run(withMockMvc((mockMvc) -> {
mockMvc.perform(options("/actuator/beans").header("Origin", "bar.example.org")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"))
.andExpect(status().isForbidden());
performAcceptedCorsRequest(mockMvc);
}));
}

@Test
void maxAgeDefaultsTo30Minutes() {
this.contextRunner.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com")
Expand Down

0 comments on commit 847bb62

Please sign in to comment.