diff --git a/spring-cloud-gateway-webflux/pom.xml b/spring-cloud-gateway-webflux/pom.xml
index 5859d52d..c74106d3 100644
--- a/spring-cloud-gateway-webflux/pom.xml
+++ b/spring-cloud-gateway-webflux/pom.xml
@@ -30,6 +30,11 @@
spring-boot-starter-actuator
test
+
+ org.springframework.boot
+ spring-boot-properties-migrator
+ test
+
org.springframework.boot
spring-boot-configuration-processor
diff --git a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyExchangeWebfluxProperties.java b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyExchangeWebfluxProperties.java
new file mode 100644
index 00000000..3c83cceb
--- /dev/null
+++ b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyExchangeWebfluxProperties.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2016-2019 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.gateway.webflux.config;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.gateway.webflux.ProxyExchange;
+import org.springframework.http.HttpHeaders;
+
+/**
+ * Configuration properties for the {@link ProxyExchange} argument handler in
+ * @RequestMapping methods.
+ *
+ * @author Dave Syer
+ * @author Tim Ysewyn
+ * @author Joris Kuipers
+ * @author Spencer Gibb
+ *
+ */
+@ConfigurationProperties(ProxyExchangeWebfluxProperties.PREFIX)
+public class ProxyExchangeWebfluxProperties {
+
+ /**
+ * Properties prefix.
+ */
+ public static final String PREFIX = "spring.cloud.gateway.proxy-exchange.webflux";
+
+ /**
+ * Contains headers that are considered case-sensitive by default.
+ */
+ public static Set DEFAULT_SENSITIVE = Set.of("cookie", "authorization");
+
+ /**
+ * Contains headers that are skipped by default.
+ */
+ public static Set DEFAULT_SKIPPED = Set.of("content-length", "host");
+
+ /**
+ * Fixed header values that will be added to all downstream requests.
+ */
+ private Map headers = new LinkedHashMap<>();
+
+ /**
+ * A set of header names that should be sent downstream by default.
+ */
+ private Set autoForward = new HashSet<>();
+
+ /**
+ * A set of sensitive header names that will not be sent downstream by default.
+ */
+ private Set sensitive = DEFAULT_SENSITIVE;
+
+ /**
+ * A set of header names that will not be sent downstream because they could be
+ * problematic.
+ */
+ private Set skipped = DEFAULT_SKIPPED;
+
+ public Map getHeaders() {
+ return headers;
+ }
+
+ public void setHeaders(Map headers) {
+ this.headers = headers;
+ }
+
+ public Set getAutoForward() {
+ return autoForward;
+ }
+
+ public void setAutoForward(Set autoForward) {
+ this.autoForward = autoForward;
+ }
+
+ public Set getSensitive() {
+ return sensitive;
+ }
+
+ public void setSensitive(Set sensitive) {
+ this.sensitive = sensitive;
+ }
+
+ public Set getSkipped() {
+ return skipped;
+ }
+
+ public void setSkipped(Set skipped) {
+ this.skipped = skipped;
+ }
+
+ public HttpHeaders convertHeaders() {
+ HttpHeaders headers = new HttpHeaders();
+ for (String key : this.headers.keySet()) {
+ headers.set(key, this.headers.get(key));
+ }
+ return headers;
+ }
+
+}
diff --git a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyProperties.java b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyProperties.java
index 38e000d5..0c7184ca 100644
--- a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyProperties.java
+++ b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyProperties.java
@@ -22,6 +22,7 @@ import java.util.Map;
import java.util.Set;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.cloud.gateway.webflux.ProxyExchange;
import org.springframework.http.HttpHeaders;
@@ -32,8 +33,10 @@ import org.springframework.http.HttpHeaders;
* @author Dave Syer
* @author Tim Ysewyn
* @author Joris Kuipers
+ * @deprecated {@link ProxyExchangeWebfluxProperties}
*
*/
+@Deprecated
@ConfigurationProperties("spring.cloud.gateway.proxy")
public class ProxyProperties {
@@ -53,7 +56,7 @@ public class ProxyProperties {
private Map headers = new LinkedHashMap<>();
/**
- * A set of header names that should be send downstream by default.
+ * A set of header names that should be sent downstream by default.
*/
private Set autoForward = new HashSet<>();
@@ -68,6 +71,7 @@ public class ProxyProperties {
*/
private Set skipped = DEFAULT_SKIPPED;
+ @DeprecatedConfigurationProperty(replacement = ProxyExchangeWebfluxProperties.PREFIX + ".headers", since = "4.3.0")
public Map getHeaders() {
return headers;
}
@@ -76,6 +80,8 @@ public class ProxyProperties {
this.headers = headers;
}
+ @DeprecatedConfigurationProperty(replacement = ProxyExchangeWebfluxProperties.PREFIX + ".auto-forward",
+ since = "4.3.0")
public Set getAutoForward() {
return autoForward;
}
@@ -84,6 +90,8 @@ public class ProxyProperties {
this.autoForward = autoForward;
}
+ @DeprecatedConfigurationProperty(replacement = ProxyExchangeWebfluxProperties.PREFIX + ".sensitive",
+ since = "4.3.0")
public Set getSensitive() {
return sensitive;
}
@@ -92,6 +100,7 @@ public class ProxyProperties {
this.sensitive = sensitive;
}
+ @DeprecatedConfigurationProperty(replacement = ProxyExchangeWebfluxProperties.PREFIX + ".skipped", since = "4.3.0")
public Set getSkipped() {
return skipped;
}
diff --git a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyResponseAutoConfiguration.java b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyResponseAutoConfiguration.java
index 20ff720d..116f0b10 100644
--- a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyResponseAutoConfiguration.java
+++ b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/config/ProxyResponseAutoConfiguration.java
@@ -48,7 +48,7 @@ import org.springframework.web.reactive.result.method.annotation.ArgumentResolve
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@ConditionalOnClass({ HandlerMethodReturnValueHandler.class, WebClient.class })
-@EnableConfigurationProperties(ProxyProperties.class)
+@EnableConfigurationProperties({ ProxyExchangeWebfluxProperties.class, ProxyProperties.class })
public class ProxyResponseAutoConfiguration implements WebFluxConfigurer {
@Autowired
@@ -57,18 +57,18 @@ public class ProxyResponseAutoConfiguration implements WebFluxConfigurer {
@Bean
@ConditionalOnMissingBean
public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver(Optional optional,
- ProxyProperties proxy) {
+ ProxyExchangeWebfluxProperties properties) {
WebClient.Builder builder = optional.orElse(WebClient.builder());
WebClient template = builder.build();
ProxyExchangeArgumentResolver resolver = new ProxyExchangeArgumentResolver(template);
- resolver.setHeaders(proxy.convertHeaders());
- resolver.setAutoForwardedHeaders(proxy.getAutoForward());
+ resolver.setHeaders(properties.convertHeaders());
+ resolver.setAutoForwardedHeaders(properties.getAutoForward());
Set excludedHeaderNames = new HashSet<>();
- if (proxy.getSensitive() != null) {
- excludedHeaderNames.addAll(proxy.getSensitive());
+ if (properties.getSensitive() != null) {
+ excludedHeaderNames.addAll(properties.getSensitive());
}
- if (proxy.getSkipped() != null) {
- excludedHeaderNames.addAll(proxy.getSkipped());
+ if (properties.getSkipped() != null) {
+ excludedHeaderNames.addAll(properties.getSkipped());
}
resolver.setExcluded(excludedHeaderNames);
return resolver;
diff --git a/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/ProductionConfigurationTests.java b/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/ProductionConfigurationTests.java
index 62b26201..732f71f8 100644
--- a/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/ProductionConfigurationTests.java
+++ b/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/ProductionConfigurationTests.java
@@ -62,7 +62,8 @@ import org.springframework.web.util.UriComponentsBuilder;
import static org.assertj.core.api.Assertions.assertThat;
-@SpringBootTest(properties = { "spring.cloud.gateway.proxy.skipped=host" }, webEnvironment = WebEnvironment.RANDOM_PORT)
+@SpringBootTest(properties = { "spring.cloud.gateway.proxy-exchange.webflux.skipped=host" },
+ webEnvironment = WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = TestApplication.class)
@DirtiesContext
@ExtendWith(OutputCaptureExtension.class)
diff --git a/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/config/ProxyExchangeWebfluxPropertiesMigrationTests.java b/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/config/ProxyExchangeWebfluxPropertiesMigrationTests.java
new file mode 100644
index 00000000..b86058a8
--- /dev/null
+++ b/spring-cloud-gateway-webflux/src/test/java/org/springframework/cloud/gateway/webflux/config/ProxyExchangeWebfluxPropertiesMigrationTests.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2013-2025 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.gateway.webflux.config;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.ActiveProfiles;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SuppressWarnings("unchecked")
+@SpringBootTest(properties = {}, webEnvironment = WebEnvironment.RANDOM_PORT)
+@ActiveProfiles("propertiesmigrationtests")
+public class ProxyExchangeWebfluxPropertiesMigrationTests {
+
+ @Autowired
+ ProxyProperties properties;
+
+ @Test
+ public void deprecatedRoutePropertiesWork() {
+ assertThat(properties.getHeaders()).hasSize(2);
+ assertThat(properties.getAutoForward()).hasSize(2);
+ assertThat(properties.getSensitive()).hasSize(2);
+ assertThat(properties.getSkipped()).hasSize(3);
+ }
+
+ @SpringBootConfiguration
+ @EnableAutoConfiguration
+ protected static class TestConfiguration {
+
+ }
+
+}
diff --git a/spring-cloud-gateway-webflux/src/test/resources/application-propertiesmigrationtests.yml b/spring-cloud-gateway-webflux/src/test/resources/application-propertiesmigrationtests.yml
new file mode 100644
index 00000000..3d9b1d93
--- /dev/null
+++ b/spring-cloud-gateway-webflux/src/test/resources/application-propertiesmigrationtests.yml
@@ -0,0 +1,12 @@
+spring.cloud.gateway.proxy:
+ headers:
+ X-Foo: xfooval
+ X-Bar: xbarval
+ auto-forward:
+ - X-FWD1
+ - X-FWD2
+ sensitive: X-S1, X-S21
+ skipped: X-SK1, X-SK2, X-SK3
+logging:
+ level:
+ org.springframework.cloud.gateway.server.mvc: TRACE