diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java index f3b6907e10..892cc9123a 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GrpcSslConfigurer.java @@ -25,6 +25,8 @@ import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +import org.springframework.util.CollectionUtils; + /** * @author Alberto C. RĂ­os */ @@ -53,6 +55,14 @@ private SslContext getSslContext() throws SSLException { sslContextBuilder.trustManager(getTrustedX509CertificatesForTrustManager()); } + if (!CollectionUtils.isEmpty(ssl.getProtocols())) { + sslContextBuilder.protocols(ssl.getProtocols()); + } + + if (!CollectionUtils.isEmpty(ssl.getCiphers())) { + sslContextBuilder.ciphers(ssl.getCiphers()); + } + return sslContextBuilder.keyManager(getKeyManagerFactory()).build(); } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java index 1071931bee..990b72f1df 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java @@ -416,6 +416,12 @@ public static class Ssl { /** Key password, default is same as keyStorePassword. */ private String keyPassword; + /** The protocols to enable, or empty to enable the default protocols. */ + private List protocols = new ArrayList<>(); + + /** The cipher suites to enable, in the order of preference. empty to use default cipher suites. */ + private List ciphers = new ArrayList<>(); + public String getKeyStorePassword() { return keyStorePassword; } @@ -456,6 +462,22 @@ public void setKeyPassword(String keyPassword) { this.keyPassword = keyPassword; } + public List getProtocols() { + return protocols; + } + + public void setProtocols(List protocols) { + this.protocols = protocols; + } + + public List getCiphers() { + return ciphers; + } + + public void setCiphers(List ciphers) { + this.ciphers = ciphers; + } + public List getTrustedX509Certificates() { return trustedX509Certificates; } diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java index 0938a8914c..3d65376e03 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientSslConfigurer.java @@ -25,6 +25,7 @@ import reactor.netty.tcp.SslProvider; import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.util.CollectionUtils; public class HttpClientSslConfigurer extends AbstractSslConfigurer { @@ -60,6 +61,13 @@ else if (ssl.isUseInsecureTrustManager()) { setTrustManager(sslContextBuilder, InsecureTrustManagerFactory.INSTANCE); } + if (!CollectionUtils.isEmpty(ssl.getProtocols())) { + sslContextBuilder.protocols(ssl.getProtocols()); + } + if (!CollectionUtils.isEmpty(ssl.getCiphers())) { + sslContextBuilder.ciphers(ssl.getCiphers()); + } + try { sslContextBuilder.keyManager(getKeyManagerFactory()); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java new file mode 100644 index 0000000000..e5ed445213 --- /dev/null +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/test/ssl/ForcedClientProtocolsSSLTests.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2020 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.test.ssl; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest(webEnvironment = RANDOM_PORT) +@DirtiesContext +@ActiveProfiles("forced-client-protocols-ssl") +public class ForcedClientProtocolsSSLTests extends SingleCertSSLTests { + +} diff --git a/spring-cloud-gateway-server/src/test/resources/application-forced-client-protocols-ssl.yml b/spring-cloud-gateway-server/src/test/resources/application-forced-client-protocols-ssl.yml new file mode 100644 index 0000000000..dc22e06ac0 --- /dev/null +++ b/spring-cloud-gateway-server/src/test/resources/application-forced-client-protocols-ssl.yml @@ -0,0 +1,13 @@ +spring: + cloud: + gateway: + httpclient: + ssl: + protocols: + - TLSv1.3 + - TLSv1.2 + - TLSv1.1 + - TLSv1 + ciphers: + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256