diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/MongoHealthIndicatorTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/MongoHealthIndicatorTests.java index b60b104c5d..bd3938f593 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/MongoHealthIndicatorTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/MongoHealthIndicatorTests.java @@ -36,7 +36,7 @@ import static org.junit.Assert.assertTrue; /** * Tests for {@link MongoHealthIndicator}. - * + * * @author Christian Dupuis */ public class MongoHealthIndicatorTests { diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc index 469f6947a8..e0219be5ff 100644 --- a/spring-boot-docs/src/main/asciidoc/howto.adoc +++ b/spring-boot-docs/src/main/asciidoc/howto.adoc @@ -387,6 +387,8 @@ and then inject the actual (``local'') port as a `@Value`. For example: } ---- + + [[howto-configure-ssl]] === Configure SSL SSL can be configured declaratively by setting the various `server.ssl.*` properties, diff --git a/spring-boot-samples/spring-boot-sample-tomcat-ssl/src/main/java/sample/tomcat/SampleTomcatSslApplication.java b/spring-boot-samples/spring-boot-sample-tomcat-ssl/src/main/java/sample/tomcat/SampleTomcatSslApplication.java index ec8443e36c..d6b6abce3e 100644 --- a/spring-boot-samples/spring-boot-sample-tomcat-ssl/src/main/java/sample/tomcat/SampleTomcatSslApplication.java +++ b/spring-boot-samples/spring-boot-sample-tomcat-ssl/src/main/java/sample/tomcat/SampleTomcatSslApplication.java @@ -31,4 +31,5 @@ public class SampleTomcatSslApplication { public static void main(String[] args) throws Exception { SpringApplication.run(SampleTomcatSslApplication.class, args); } + } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractConfigurableEmbeddedServletContainer.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractConfigurableEmbeddedServletContainer.java index f341ffd2c4..2206e6b82a 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractConfigurableEmbeddedServletContainer.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/AbstractConfigurableEmbeddedServletContainer.java @@ -244,11 +244,6 @@ public abstract class AbstractConfigurableEmbeddedServletContainer implements return this.registerDefaultServlet; } - @Override - public void setJspServletClassName(String jspServletClassName) { - this.jspServletClassName = jspServletClassName; - } - @Override public void setSsl(Ssl ssl) { this.ssl = ssl; @@ -258,6 +253,11 @@ public abstract class AbstractConfigurableEmbeddedServletContainer implements return this.ssl; } + @Override + public void setJspServletClassName(String jspServletClassName) { + this.jspServletClassName = jspServletClassName; + } + /** * @return the JSP servlet class name */ diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java index 39d66a68f9..5268dc1ee5 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/jetty/JettyEmbeddedServletContainerFactory.java @@ -19,6 +19,7 @@ package org.springframework.boot.context.embedded.jetty; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; +import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -69,7 +70,7 @@ import org.springframework.util.StringUtils; * @see JettyEmbeddedServletContainer */ public class JettyEmbeddedServletContainerFactory extends -AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { + AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { private List configurations = new ArrayList(); @@ -115,7 +116,7 @@ AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { if (getSsl() != null) { SslContextFactory sslContextFactory = new SslContextFactory(); - configureSslContextFactory(sslContextFactory, getSsl()); + configureSsl(sslContextFactory, getSsl()); SslSocketConnector sslConnector = new SslSocketConnector(sslContextFactory); sslConnector.setPort(port); @@ -129,47 +130,65 @@ AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { return getJettyEmbeddedServletContainer(server); } - protected void configureSslContextFactory(SslContextFactory sslContextFactory, Ssl ssl) { - sslContextFactory.setProtocol(ssl.getProtocol()); + /** + * Configure the SSL connection. + * @param factory the Jetty {@link SslContextFactory}. + * @param ssl the ssl details. + */ + protected void configureSsl(SslContextFactory factory, Ssl ssl) { + factory.setProtocol(ssl.getProtocol()); + configureSslClientAuth(factory, ssl); + configureSslPasswords(factory, ssl); + factory.setCertAlias(ssl.getKeyAlias()); + configureSslKeyStore(factory, ssl); + if (ssl.getCiphers() != null) { + factory.setIncludeCipherSuites(ssl.getCiphers()); + } + configureSslTrustStore(factory, ssl); + } + + private void configureSslClientAuth(SslContextFactory factory, Ssl ssl) { if (ssl.getClientAuth() == ClientAuth.NEED) { - sslContextFactory.setNeedClientAuth(true); - sslContextFactory.setWantClientAuth(true); + factory.setNeedClientAuth(true); + factory.setWantClientAuth(true); } else if (ssl.getClientAuth() == ClientAuth.WANT) { - sslContextFactory.setWantClientAuth(true); + factory.setWantClientAuth(true); } + } + + private void configureSslPasswords(SslContextFactory factory, Ssl ssl) { if (ssl.getKeyStorePassword() != null) { - sslContextFactory.setKeyStorePassword(ssl.getKeyStorePassword()); + factory.setKeyStorePassword(ssl.getKeyStorePassword()); } if (ssl.getKeyPassword() != null) { - sslContextFactory.setKeyManagerPassword(ssl.getKeyPassword()); + factory.setKeyManagerPassword(ssl.getKeyPassword()); } - sslContextFactory.setCertAlias(ssl.getKeyAlias()); + } + + private void configureSslKeyStore(SslContextFactory factory, Ssl ssl) { try { - sslContextFactory.setKeyStoreResource(Resource.newResource(ResourceUtils - .getURL(ssl.getKeyStore()))); + URL url = ResourceUtils.getURL(ssl.getKeyStore()); + factory.setKeyStoreResource(Resource.newResource(url)); } - catch (IOException e) { + catch (IOException ex) { throw new EmbeddedServletContainerException("Could not find key store '" - + ssl.getKeyStore() + "'", e); - } - - if (ssl.getCiphers() != null) { - sslContextFactory.setIncludeCipherSuites(ssl.getCiphers()); + + ssl.getKeyStore() + "'", ex); } + } + private void configureSslTrustStore(SslContextFactory factory, Ssl ssl) { if (ssl.getTrustStorePassword() != null) { - sslContextFactory.setTrustStorePassword(ssl.getTrustStorePassword()); + factory.setTrustStorePassword(ssl.getTrustStorePassword()); } - if (ssl.getTrustStore() != null) { try { - sslContextFactory.setTrustStoreResource(Resource - .newResource(ResourceUtils.getURL(ssl.getTrustStore()))); + URL url = ResourceUtils.getURL(ssl.getTrustStore()); + factory.setTrustStoreResource(Resource.newResource(url)); } - catch (IOException e) { + catch (IOException ex) { throw new EmbeddedServletContainerException( - "Could not find trust store '" + ssl.getTrustStore() + "'", e); + "Could not find trust store '" + ssl.getTrustStore() + "'", ex); } } } @@ -202,7 +221,7 @@ AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { initializersToUse); context.setConfigurations(configurations); context.getSessionHandler().getSessionManager() - .setMaxInactiveInterval(getSessionTimeout()); + .setMaxInactiveInterval(getSessionTimeout()); postProcessWebAppContext(context); } @@ -211,8 +230,8 @@ AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { if (root != null) { try { if (!root.isDirectory()) { - handler.setBaseResource(Resource.newResource("jar:" + root.toURI() - + "!")); + Resource resource = Resource.newResource("jar:" + root.toURI() + "!"); + handler.setBaseResource(resource); } else { handler.setBaseResource(Resource.newResource(root)); diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index f56619496d..8838009657 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -79,7 +79,7 @@ import org.springframework.util.StringUtils; * @see TomcatEmbeddedServletContainer */ public class TomcatEmbeddedServletContainerFactory extends -AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { + AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { private static final String DEFAULT_PROTOCOL = "org.apache.coyote.http11.Http11NioProtocol"; @@ -226,7 +226,7 @@ AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { if (connector.getProtocolHandler() instanceof AbstractProtocol) { if (getAddress() != null) { ((AbstractProtocol) connector.getProtocolHandler()) - .setAddress(getAddress()); + .setAddress(getAddress()); } } if (getUriEncoding() != null) { @@ -238,17 +238,14 @@ AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { connector.setProperty("bindOnInit", "false"); if (getSsl() != null) { - if (connector.getProtocolHandler() instanceof AbstractHttp11JsseProtocol) { - AbstractHttp11JsseProtocol jsseProtocol = (AbstractHttp11JsseProtocol) connector - .getProtocolHandler(); - configureJsseProtocol(jsseProtocol, getSsl()); - connector.setScheme("https"); - connector.setSecure(true); - } - else { - throw new IllegalStateException( - "To use SSL, the connector's protocol handler must be an AbstractHttp11JsseProtocol subclass"); - } + Assert.state( + connector.getProtocolHandler() instanceof AbstractHttp11JsseProtocol, + "To use SSL, the connector's protocol handler must be an " + + "AbstractHttp11JsseProtocol subclass"); + configureSsl((AbstractHttp11JsseProtocol) connector.getProtocolHandler(), + getSsl()); + connector.setScheme("https"); + connector.setSecure(true); } for (TomcatConnectorCustomizer customizer : this.tomcatConnectorCustomizers) { @@ -256,42 +253,56 @@ AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware { } } - protected void configureJsseProtocol(AbstractHttp11JsseProtocol jsseProtocol, Ssl ssl) { - jsseProtocol.setSSLEnabled(true); - jsseProtocol.setSslProtocol(ssl.getProtocol()); + /** + * Configure Tomcat's {@link AbstractHttp11JsseProtocol} for SSL. + * @param protocol the protocol + * @param ssl the ssl details + */ + protected void configureSsl(AbstractHttp11JsseProtocol protocol, Ssl ssl) { + protocol.setSSLEnabled(true); + protocol.setSslProtocol(ssl.getProtocol()); + configureSslClientAuth(protocol, ssl); + protocol.setKeystorePass(ssl.getKeyStorePassword()); + protocol.setKeyPass(ssl.getKeyPassword()); + protocol.setKeyAlias(ssl.getKeyAlias()); + configureSslKeyStore(protocol, ssl); + String ciphers = StringUtils.arrayToCommaDelimitedString(ssl.getCiphers()); + protocol.setCiphers(ciphers); + configureSslTrustStore(protocol, ssl); + } + + private void configureSslClientAuth(AbstractHttp11JsseProtocol protocol, Ssl ssl) { if (ssl.getClientAuth() == ClientAuth.NEED) { - jsseProtocol.setClientAuth(Boolean.TRUE.toString()); + protocol.setClientAuth(Boolean.TRUE.toString()); } else if (ssl.getClientAuth() == ClientAuth.WANT) { - jsseProtocol.setClientAuth("want"); + protocol.setClientAuth("want"); } - jsseProtocol.setKeystorePass(ssl.getKeyStorePassword()); - jsseProtocol.setKeyPass(ssl.getKeyPassword()); - jsseProtocol.setKeyAlias(ssl.getKeyAlias()); + } + + private void configureSslKeyStore(AbstractHttp11JsseProtocol protocol, Ssl ssl) { try { - jsseProtocol.setKeystoreFile(ResourceUtils.getFile(ssl.getKeyStore()) - .getAbsolutePath()); + File file = ResourceUtils.getFile(ssl.getKeyStore()); + protocol.setKeystoreFile(file.getAbsolutePath()); } - catch (FileNotFoundException e) { + catch (FileNotFoundException ex) { throw new EmbeddedServletContainerException("Could not find key store " - + ssl.getKeyStore(), e); + + ssl.getKeyStore(), ex); } + } - jsseProtocol - .setCiphers(StringUtils.arrayToCommaDelimitedString(ssl.getCiphers())); - + private void configureSslTrustStore(AbstractHttp11JsseProtocol protocol, Ssl ssl) { if (ssl.getTrustStore() != null) { try { - jsseProtocol.setTruststoreFile(ResourceUtils.getFile(ssl.getTrustStore()) - .getAbsolutePath()); + File file = ResourceUtils.getFile(ssl.getTrustStore()); + protocol.setTruststoreFile(file.getAbsolutePath()); } - catch (FileNotFoundException e) { + catch (FileNotFoundException ex) { throw new EmbeddedServletContainerException("Could not find trust store " - + ssl.getTrustStore(), e); + + ssl.getTrustStore(), ex); } } - - jsseProtocol.setTruststorePass(ssl.getTrustStorePassword()); + protocol.setTruststorePass(ssl.getTrustStorePassword()); } /**