diff --git a/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java b/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java index b947e018391..4864739e4c1 100644 --- a/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java +++ b/module/spring-boot-tomcat/src/main/java/org/springframework/boot/tomcat/SslConnectorCustomizer.java @@ -68,13 +68,7 @@ public class SslConnectorCustomizer { AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) this.connector.getProtocolHandler(); String hostName = (serverName != null) ? serverName : protocol.getDefaultSSLHostConfigName(); this.logger.debug("SSL Bundle for host " + hostName + " has been updated, reloading SSL configuration"); - SSLHostConfig sslHostConfig = findSslHostConfig(protocol, hostName); - if (sslHostConfig == null) { - addSslHostConfig(protocol, hostName, updatedSslBundle); - return; - } - applySslBundle(protocol, sslHostConfig, updatedSslBundle); - protocol.addSslHostConfig(sslHostConfig, true); + configureSslHostConfig(protocol, hostName, updatedSslBundle); } public void customize(SslBundle sslBundle, Map serverNameSslBundles) { @@ -96,15 +90,18 @@ public class SslConnectorCustomizer { Map serverNameSslBundles) { protocol.setSSLEnabled(true); if (sslBundle != null) { - addSslHostConfig(protocol, protocol.getDefaultSSLHostConfigName(), sslBundle); + configureSslHostConfig(protocol, protocol.getDefaultSSLHostConfigName(), sslBundle); } - serverNameSslBundles.forEach((serverName, bundle) -> addSslHostConfig(protocol, serverName, bundle)); + serverNameSslBundles.forEach((serverName, bundle) -> configureSslHostConfig(protocol, serverName, bundle)); } - private void addSslHostConfig(AbstractHttp11Protocol protocol, String hostName, SslBundle sslBundle) { - SSLHostConfig sslHostConfig = new SSLHostConfig(); - sslHostConfig.setHostName(hostName); - configureSslClientAuth(sslHostConfig); + private void configureSslHostConfig(AbstractHttp11Protocol protocol, String hostName, SslBundle sslBundle) { + SSLHostConfig sslHostConfig = findSslHostConfig(protocol, hostName); + if (sslHostConfig == null) { + sslHostConfig = new SSLHostConfig(); + sslHostConfig.setHostName(hostName); + configureSslClientAuth(sslHostConfig); + } applySslBundle(protocol, sslHostConfig, sslBundle); protocol.addSslHostConfig(sslHostConfig, true); } diff --git a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java index d362b4e1d5c..a7e39d3b7b1 100644 --- a/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java +++ b/module/spring-boot-tomcat/src/test/java/org/springframework/boot/tomcat/SslConnectorCustomizerTests.java @@ -24,6 +24,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.coyote.http11.AbstractHttp11Protocol; import org.apache.tomcat.util.net.SSLHostConfig; +import org.apache.tomcat.util.net.SSLHostConfig.CertificateVerification; import org.apache.tomcat.util.net.openssl.ciphers.Cipher; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -158,6 +159,26 @@ class SslConnectorCustomizerTests { assertThat(sslHostConfig.getEnabledProtocols()).containsExactly("TLSv1.2"); } + @Test + @WithPackageResources("test.jks") + void customizeRetainsCustomizationsAppliedToExistingSslHostConfig() { + Ssl ssl = new Ssl(); + ssl.setKeyPassword("password"); + ssl.setKeyStore("classpath:test.jks"); + Connector connector = this.tomcat.getConnector(); + AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) connector.getProtocolHandler(); + SSLHostConfig existing = new SSLHostConfig(); + existing.setHostName(protocol.getDefaultSSLHostConfigName()); + existing.setTruststoreProvider(MockPkcs11SecurityProvider.NAME); + protocol.addSslHostConfig(existing); + SslConnectorCustomizer customizer = new SslConnectorCustomizer(this.logger, connector, ssl.getClientAuth()); + customizer.customize(WebServerSslBundle.get(ssl), Collections.emptyMap()); + assertThat(protocol.findSslHostConfigs()).hasSize(1); + SSLHostConfig sslHostConfig = protocol.findSslHostConfigs()[0]; + assertThat(sslHostConfig.getTruststoreProvider()).isEqualTo(MockPkcs11SecurityProvider.NAME); + assertThat(sslHostConfig.getCertificates()).hasSize(1); + } + @Test @WithPackageResources("test.jks") void updateRetainsCustomizationsAppliedToSslHostConfig() { @@ -177,6 +198,23 @@ class SslConnectorCustomizerTests { assertThat(updated.getCertificates()).hasSize(1); } + @Test + @WithPackageResources("test.jks") + void updateRetainsClientAuthConfiguredOnSslHostConfig() { + Ssl ssl = new Ssl(); + ssl.setKeyPassword("password"); + ssl.setKeyStore("classpath:test.jks"); + Connector connector = this.tomcat.getConnector(); + AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) connector.getProtocolHandler(); + SslConnectorCustomizer customizer = new SslConnectorCustomizer(this.logger, connector, ssl.getClientAuth()); + customizer.customize(WebServerSslBundle.get(ssl), Collections.emptyMap()); + SSLHostConfig sslHostConfig = protocol.findSslHostConfigs()[0]; + sslHostConfig.setCertificateVerification("required"); + customizer.update(null, WebServerSslBundle.get(ssl)); + SSLHostConfig updated = protocol.findSslHostConfigs()[0]; + assertThat(updated.getCertificateVerification()).isEqualTo(CertificateVerification.REQUIRED); + } + @Test @WithPackageResources("test.jks") void updateAppliesUpdatedBundleToExistingSslHostConfig() throws Exception {