This is an automated email from the ASF dual-hosted git repository.
yui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 13a236a76 [type: refactor] support custom origins for cors
'Acess-Control-Allow-Origin'. (#3663)
13a236a76 is described below
commit 13a236a765ec24f5056d22cf8962b800f51f290e
Author: Qicz <[email protected]>
AuthorDate: Tue Jul 5 14:09:14 2022 +0800
[type: refactor] support custom origins for cors
'Acess-Control-Allow-Origin'. (#3663)
* [type: refactor] support custom origins for cors
'Acess-Control-Allow-Origin'.
* trim origin item
* code polish
* optimize cors logic
---
.../src/main/resources/application.yml | 18 ++++---
.../apache/shenyu/common/config/ShenyuConfig.java | 28 +++++++---
.../org/apache/shenyu/web/filter/CrossFilter.java | 60 +++++++++++++---------
.../apache/shenyu/web/filter/CrossFilterTest.java | 1 +
4 files changed, 70 insertions(+), 37 deletions(-)
diff --git a/shenyu-bootstrap/src/main/resources/application.yml
b/shenyu-bootstrap/src/main/resources/application.yml
index 16e7c0b13..b396fbb39 100644
--- a/shenyu-bootstrap/src/main/resources/application.yml
+++ b/shenyu-bootstrap/src/main/resources/application.yml
@@ -160,15 +160,19 @@ shenyu:
enabled: true
allowedHeaders:
allowedMethods: "*"
- allowedAnyOrigin: false
- allowedOrigin:
+ allowedAnyOrigin: true # the same of Access-Control-Allow-Origin: "*"
+# allowedOrigin:
# format : schema://prefix spacer domain
# Access-Control-Allow-Origin: "http://a.apache.org,http://b.apache.org"
- spacer: "."
- domain: apache.org
- prefixes:
- - a # a.apache.org
- - b # b.apache.org
+# spacer: "."
+# domain: apache.org
+# prefixes:
+# - a # a.apache.org
+# - b # b.apache.org
+# origins:
+# - c.apache.org
+# - d.apache.org
+# - http://e.apache.org
allowedExpose: ""
maxAge: "18000"
allowCredentials: true
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
index 6e2e06cda..b03206f51 100644
---
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
@@ -23,7 +23,6 @@ import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
@@ -1144,6 +1143,8 @@ public class ShenyuConfig {
private Set<String> prefixes = new HashSet<>();
+ private String origins;
+
/**
* Gets the spacer.
*
@@ -1174,7 +1175,7 @@ public class ShenyuConfig {
/**
* Sets the enabled.
*
- * @param domain enabled
+ * @param domain domain
*/
public void setDomain(final String domain) {
this.domain = domain;
@@ -1186,20 +1187,35 @@ public class ShenyuConfig {
* @return the value of prefixes
*/
public Set<String> getPrefixes() {
- if (Objects.isNull(prefixes)) {
- prefixes = new HashSet<>();
- }
return prefixes;
}
/**
* Sets the enabled.
*
- * @param prefixes enabled
+ * @param prefixes prefixes
*/
public void setPrefixes(final Set<String> prefixes) {
this.prefixes = prefixes;
}
+
+ /**
+ * Gets the prefixes.
+ *
+ * @return the value of prefixes
+ */
+ public String getOrigins() {
+ return origins;
+ }
+
+ /**
+ * Sets the origins.
+ *
+ * @param origins origins
+ */
+ public void setOrigins(final String origins) {
+ this.origins = origins;
+ }
}
}
diff --git
a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java
b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java
index b4a179b54..6a9a81d37 100644
--- a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java
+++ b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java
@@ -32,8 +32,10 @@ import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -58,15 +60,13 @@ public class CrossFilter implements WebFilter {
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
- // "Access-Control-Allow-Origin"
+ // finger allow origins
final String origin = request.getHeaders().getOrigin();
- if (this.filterConfig.isAllowedAnyOrigin()) {
- headers.set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
- } else if (Objects.nonNull(this.filterConfig.getAllowedOrigin())
- &&
CollectionUtils.isNotEmpty(this.filterConfig.getAllowedOrigin().getPrefixes()))
{
+ boolean allowCors = this.filterConfig.isAllowedAnyOrigin();
+ if (!allowCors &&
Objects.nonNull(this.filterConfig.getAllowedOrigin())) {
final String scheme =
exchange.getRequest().getURI().getScheme();
final CrossFilterConfig.AllowedOriginConfig
allowedOriginConfig = this.filterConfig.getAllowedOrigin();
- Set<String> allowedOrigin = allowedOriginConfig.getPrefixes()
+ Set<String> allowedOrigin =
Optional.ofNullable(allowedOriginConfig.getPrefixes()).orElse(Collections.emptySet())
.stream()
.filter(StringUtils::isNoneBlank)
// scheme://prefix spacer domain
@@ -75,25 +75,37 @@ public class CrossFilter implements WebFilter {
StringUtils.defaultString(allowedOriginConfig.getSpacer(), ".").trim(),
StringUtils.defaultString(allowedOriginConfig.getDomain(), "").trim()))
.collect(Collectors.toSet());
- if (allowedOrigin.contains(origin)) {
- headers.set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN,
origin);
- }
+ // add all origin domains
+
allowedOrigin.addAll(Stream.of(StringUtils.defaultString(allowedOriginConfig.getOrigins(),
"").split(","))
+ .filter(StringUtils::isNoneBlank)
+ .map(oneOrigin -> {
+ if (ALL.equals(oneOrigin) ||
oneOrigin.startsWith(String.format("%s://", scheme))) {
+ return oneOrigin.trim();
+ }
+ return String.format("%s://%s", scheme,
oneOrigin.trim());
+ })
+ .collect(Collectors.toSet()));
+ allowCors = allowedOrigin.contains(origin) ||
allowedOrigin.contains(ALL);
+ }
+ if (allowCors) {
+ // "Access-Control-Allow-Origin"
+ headers.set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
+ // "Access-Control-Allow-Methods"
+ this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,
+ this.filterConfig.getAllowedMethods());
+ // "Access-Control-Max-Age"
+ this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_MAX_AGE,
+ this.filterConfig.getMaxAge());
+ // "Access-Control-Allow-Headers"
+ this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
+ this.filterConfig.getAllowedHeaders());
+ // "Access-Control-Expose-Headers"
+ this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,
+ this.filterConfig.getAllowedExpose());
+ // "Access-Control-Allow-Credentials"
+ this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS,
+
String.valueOf(this.filterConfig.isAllowCredentials()));
}
- // "Access-Control-Allow-Methods"
- this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,
- this.filterConfig.getAllowedMethods());
- // "Access-Control-Max-Age"
- this.filterSameHeader(headers, HttpHeaders.ACCESS_CONTROL_MAX_AGE,
- this.filterConfig.getMaxAge());
- // "Access-Control-Allow-Headers"
- this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
- this.filterConfig.getAllowedHeaders());
- // "Access-Control-Expose-Headers"
- this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,
- this.filterConfig.getAllowedExpose());
- // "Access-Control-Allow-Credentials"
- this.filterSameHeader(headers,
HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS,
- String.valueOf(this.filterConfig.isAllowCredentials()));
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
diff --git
a/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CrossFilterTest.java
b/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CrossFilterTest.java
index ec942bc1c..d11503963 100644
--- a/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CrossFilterTest.java
+++ b/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CrossFilterTest.java
@@ -93,6 +93,7 @@ public final class CrossFilterTest {
add("a");
}
});
+
allowedOriginConfig.setOrigins("b.apache.org,c.apache.org,http://d.apache.org,*");
filterConfig.setAllowedOrigin(allowedOriginConfig);
CrossFilter filter = new CrossFilter(filterConfig);
StepVerifier.create(filter.filter(exchange, chainNormal))