Backport Jetty/Tomcat SSL support

Fixes gh-1570
Cherry-picked from 0960908 and 258c6f1
This commit is contained in:
Phillip Webb
2014-09-17 09:30:37 -07:00
parent fae9ab4140
commit 62a5ce52d0
20 changed files with 920 additions and 80 deletions

View File

@@ -59,6 +59,8 @@ public abstract class AbstractConfigurableEmbeddedServletContainer implements
private int sessionTimeout;
private Ssl ssl;
/**
* Create a new {@link AbstractConfigurableEmbeddedServletContainer} instance.
*/
@@ -247,6 +249,15 @@ public abstract class AbstractConfigurableEmbeddedServletContainer implements
this.jspServletClassName = jspServletClassName;
}
@Override
public void setSsl(Ssl ssl) {
this.ssl = ssl;
}
public Ssl getSsl() {
return this.ssl;
}
/**
* @return the JSP servlet class name
*/

View File

@@ -139,4 +139,11 @@ public interface ConfigurableEmbeddedServletContainer {
*/
void addInitializers(ServletContextInitializer... initializers);
/**
* Sets the SSL configuration that will be applied to the container's default
* connector.
* @param ssl the SSL configuration
*/
void setSsl(Ssl ssl);
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright 2012-2014 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
*
* http://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.boot.context.embedded;
/**
* Simple container-independent abstraction for SSL configuration.
*
* @author Andy Wilkinson
* @since 1.2.0
*/
public class Ssl {
private ClientAuth clientAuth;
private String[] ciphers;
private String keyAlias;
private String keyPassword;
private String keyStore;
private String keyStorePassword;
private String keyStoreType;
private String keyStoreProvider;
private String trustStore;
private String trustStorePassword;
private String trustStoreType;
private String trustStoreProvider;
private String protocol = "TLS";
public ClientAuth getClientAuth() {
return this.clientAuth;
}
public void setClientAuth(ClientAuth clientAuth) {
this.clientAuth = clientAuth;
}
public String[] getCiphers() {
return this.ciphers;
}
public void setCiphers(String[] ciphers) {
this.ciphers = ciphers;
}
public String getKeyAlias() {
return this.keyAlias;
}
public void setKeyAlias(String keyAlias) {
this.keyAlias = keyAlias;
}
public String getKeyPassword() {
return this.keyPassword;
}
public void setKeyPassword(String keyPassword) {
this.keyPassword = keyPassword;
}
public String getKeyStore() {
return this.keyStore;
}
public void setKeyStore(String keyStore) {
this.keyStore = keyStore;
}
public String getKeyStorePassword() {
return this.keyStorePassword;
}
public void setKeyStorePassword(String keyStorePassword) {
this.keyStorePassword = keyStorePassword;
}
public String getKeyStoreType() {
return this.keyStoreType;
}
public void setKeyStoreType(String keyStoreType) {
this.keyStoreType = keyStoreType;
}
public String getKeyStoreProvider() {
return this.keyStoreProvider;
}
public void setKeyStoreProvider(String keyStoreProvider) {
this.keyStoreProvider = keyStoreProvider;
}
public String getTrustStore() {
return this.trustStore;
}
public void setTrustStore(String trustStore) {
this.trustStore = trustStore;
}
public String getTrustStorePassword() {
return this.trustStorePassword;
}
public void setTrustStorePassword(String trustStorePassword) {
this.trustStorePassword = trustStorePassword;
}
public String getTrustStoreType() {
return this.trustStoreType;
}
public void setTrustStoreType(String trustStoreType) {
this.trustStoreType = trustStoreType;
}
public String getTrustStoreProvider() {
return this.trustStoreProvider;
}
public void setTrustStoreProvider(String trustStoreProvider) {
this.trustStoreProvider = trustStoreProvider;
}
public String getProtocol() {
return this.protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public enum ClientAuth {
WANT, NEED;
}
}

View File

@@ -17,32 +17,41 @@
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;
import java.util.List;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.ssl.SslSocketConnector;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlet.ServletMapping;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerException;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.boot.context.embedded.MimeMappings;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
/**
@@ -104,6 +113,16 @@ public class JettyEmbeddedServletContainerFactory extends
configureWebAppContext(context, initializers);
server.setHandler(context);
this.logger.info("Server initialized with port: " + port);
if (getSsl() != null) {
SslContextFactory sslContextFactory = new SslContextFactory();
configureSsl(sslContextFactory, getSsl());
SslSocketConnector sslConnector = new SslSocketConnector(sslContextFactory);
sslConnector.setPort(port);
server.setConnectors(new Connector[] { sslConnector });
}
for (JettyServerCustomizer customizer : getServerCustomizers()) {
customizer.customize(server);
}
@@ -111,6 +130,81 @@ public class JettyEmbeddedServletContainerFactory extends
return getJettyEmbeddedServletContainer(server);
}
/**
* 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) {
factory.setNeedClientAuth(true);
factory.setWantClientAuth(true);
}
else if (ssl.getClientAuth() == ClientAuth.WANT) {
factory.setWantClientAuth(true);
}
}
private void configureSslPasswords(SslContextFactory factory, Ssl ssl) {
if (ssl.getKeyStorePassword() != null) {
factory.setKeyStorePassword(ssl.getKeyStorePassword());
}
if (ssl.getKeyPassword() != null) {
factory.setKeyManagerPassword(ssl.getKeyPassword());
}
}
private void configureSslKeyStore(SslContextFactory factory, Ssl ssl) {
try {
URL url = ResourceUtils.getURL(ssl.getKeyStore());
factory.setKeyStoreResource(Resource.newResource(url));
}
catch (IOException ex) {
throw new EmbeddedServletContainerException("Could not find key store '"
+ ssl.getKeyStore() + "'", ex);
}
if (ssl.getKeyStoreType() != null) {
factory.setKeyStoreType(ssl.getKeyStoreType());
}
if (ssl.getKeyStoreProvider() != null) {
factory.setKeyStoreProvider(ssl.getKeyStoreProvider());
}
}
private void configureSslTrustStore(SslContextFactory factory, Ssl ssl) {
if (ssl.getTrustStorePassword() != null) {
factory.setTrustStorePassword(ssl.getTrustStorePassword());
}
if (ssl.getTrustStore() != null) {
try {
URL url = ResourceUtils.getURL(ssl.getTrustStore());
factory.setTrustStoreResource(Resource.newResource(url));
}
catch (IOException ex) {
throw new EmbeddedServletContainerException(
"Could not find trust store '" + ssl.getTrustStore() + "'", ex);
}
}
if (ssl.getTrustStoreType() != null) {
factory.setTrustStoreType(ssl.getTrustStoreType());
}
if (ssl.getTrustStoreProvider() != null) {
factory.setTrustStoreProvider(ssl.getTrustStoreProvider());
}
}
/**
* Configure the given Jetty {@link WebAppContext} for use.
* @param context the context to configure

View File

@@ -17,6 +17,7 @@
package org.springframework.boot.context.embedded.tomcat;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
@@ -42,6 +43,7 @@ import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.Tomcat.FixContextListener;
import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.http11.AbstractHttp11JsseProtocol;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
@@ -50,12 +52,16 @@ import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
import org.springframework.boot.context.embedded.ErrorPage;
import org.springframework.boot.context.embedded.MimeMappings;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
/**
* {@link EmbeddedServletContainerFactory} that can be used to create
@@ -231,11 +237,87 @@ public class TomcatEmbeddedServletContainerFactory extends
// If ApplicationContext is slow to start we want Tomcat not to bind to the socket
// prematurely...
connector.setProperty("bindOnInit", "false");
if (getSsl() != null) {
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) {
customizer.customize(connector);
}
}
/**
* 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) {
protocol.setClientAuth(Boolean.TRUE.toString());
}
else if (ssl.getClientAuth() == ClientAuth.WANT) {
protocol.setClientAuth("want");
}
}
private void configureSslKeyStore(AbstractHttp11JsseProtocol<?> protocol, Ssl ssl) {
try {
File file = ResourceUtils.getFile(ssl.getKeyStore());
protocol.setKeystoreFile(file.getAbsolutePath());
}
catch (FileNotFoundException ex) {
throw new EmbeddedServletContainerException("Could not find key store "
+ ssl.getKeyStore(), ex);
}
if (ssl.getKeyStoreType() != null) {
protocol.setKeystoreType(ssl.getKeyStoreType());
}
if (ssl.getKeyStoreProvider() != null) {
protocol.setKeystoreProvider(ssl.getKeyStoreProvider());
}
}
private void configureSslTrustStore(AbstractHttp11JsseProtocol<?> protocol, Ssl ssl) {
if (ssl.getTrustStore() != null) {
try {
File file = ResourceUtils.getFile(ssl.getTrustStore());
protocol.setTruststoreFile(file.getAbsolutePath());
}
catch (FileNotFoundException ex) {
throw new EmbeddedServletContainerException("Could not find trust store "
+ ssl.getTrustStore(), ex);
}
}
protocol.setTruststorePass(ssl.getTrustStorePassword());
if (ssl.getTrustStoreType() != null) {
protocol.setTruststoreType(ssl.getTrustStoreType());
}
if (ssl.getTrustStoreProvider() != null) {
protocol.setTruststoreProvider(ssl.getTrustStoreProvider());
}
}
/**
* Configure the Tomcat {@link Context}.
* @param context the Tomcat context

View File

@@ -16,11 +16,14 @@
package org.springframework.boot.context.embedded;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.TimeUnit;
@@ -31,12 +34,18 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.mockito.InOrder;
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpRequest;
@@ -62,6 +71,7 @@ import static org.mockito.Mockito.mock;
*
* @author Phillip Webb
* @author Greg Turnquist
* @author Andy Wilkinson
*/
public abstract class AbstractEmbeddedServletContainerFactoryTests {
@@ -300,8 +310,232 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
assertThat(getResponse(getLocalUrl("/bang")), equalTo("Hello World"));
}
@Test
public void basicSsl() throws Exception {
FileCopyUtils.copy("test",
new FileWriter(this.temporaryFolder.newFile("test.txt")));
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.setDocumentRoot(this.temporaryFolder.getRoot());
Ssl ssl = new Ssl();
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyStorePassword("secret");
ssl.setKeyPassword("password");
factory.setSsl(ssl);
this.container = factory.getEmbeddedServletContainer();
this.container.start();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
new SSLContextBuilder().loadTrustMaterial(null,
new TrustSelfSignedStrategy()).build());
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory),
equalTo("test"));
}
@Test
public void pkcs12KeyStoreAndTrustStore() throws Exception {
FileCopyUtils.copy("test",
new FileWriter(this.temporaryFolder.newFile("test.txt")));
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.setDocumentRoot(this.temporaryFolder.getRoot());
Ssl ssl = new Ssl();
ssl.setKeyStore("src/test/resources/test.p12");
ssl.setKeyStorePassword("secret");
ssl.setKeyStoreType("pkcs12");
ssl.setTrustStore("src/test/resources/test.p12");
ssl.setTrustStorePassword("secret");
ssl.setTrustStoreType("pkcs12");
ssl.setClientAuth(ClientAuth.NEED);
factory.setSsl(ssl);
this.container = factory.getEmbeddedServletContainer();
this.container.start();
KeyStore keyStore = KeyStore.getInstance("pkcs12");
keyStore.load(new FileInputStream(new File("src/test/resources/test.p12")),
"secret".toCharArray());
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
new SSLContextBuilder()
.loadTrustMaterial(null, new TrustSelfSignedStrategy())
.loadKeyMaterial(keyStore, "secret".toCharArray()).build());
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory),
equalTo("test"));
}
@Test
public void sslNeedsClientAuthenticationSucceedsWithClientCertificate()
throws Exception {
FileCopyUtils.copy("test",
new FileWriter(this.temporaryFolder.newFile("test.txt")));
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.setDocumentRoot(this.temporaryFolder.getRoot());
Ssl ssl = new Ssl();
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyStorePassword("secret");
ssl.setKeyPassword("password");
ssl.setClientAuth(ClientAuth.NEED);
ssl.setTrustStore("src/test/resources/test.jks");
ssl.setTrustStorePassword("secret");
factory.setSsl(ssl);
this.container = factory.getEmbeddedServletContainer();
this.container.start();
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(new FileInputStream(new File("src/test/resources/test.jks")),
"secret".toCharArray());
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
new SSLContextBuilder()
.loadTrustMaterial(null, new TrustSelfSignedStrategy())
.loadKeyMaterial(keyStore, "password".toCharArray()).build());
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory),
equalTo("test"));
}
@Test(expected = IOException.class)
public void sslNeedsClientAuthenticationFailsWithoutClientCertificate()
throws Exception {
FileCopyUtils.copy("test",
new FileWriter(this.temporaryFolder.newFile("test.txt")));
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.setDocumentRoot(this.temporaryFolder.getRoot());
Ssl ssl = new Ssl();
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyStorePassword("secret");
ssl.setKeyPassword("password");
ssl.setClientAuth(ClientAuth.NEED);
ssl.setTrustStore("src/test/resources/test.jks");
ssl.setTrustStorePassword("secret");
factory.setSsl(ssl);
this.container = factory.getEmbeddedServletContainer();
this.container.start();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
new SSLContextBuilder().loadTrustMaterial(null,
new TrustSelfSignedStrategy()).build());
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
getResponse(getLocalUrl("https", "/test.txt"), requestFactory);
}
@Test
public void sslWantsClientAuthenticationSucceedsWithClientCertificate()
throws Exception {
FileCopyUtils.copy("test",
new FileWriter(this.temporaryFolder.newFile("test.txt")));
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.setDocumentRoot(this.temporaryFolder.getRoot());
Ssl ssl = new Ssl();
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyStorePassword("secret");
ssl.setKeyPassword("password");
ssl.setClientAuth(ClientAuth.WANT);
ssl.setTrustStore("src/test/resources/test.jks");
ssl.setTrustStorePassword("secret");
factory.setSsl(ssl);
this.container = factory.getEmbeddedServletContainer();
this.container.start();
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(new FileInputStream(new File("src/test/resources/test.jks")),
"secret".toCharArray());
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
new SSLContextBuilder()
.loadTrustMaterial(null, new TrustSelfSignedStrategy())
.loadKeyMaterial(keyStore, "password".toCharArray()).build());
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory),
equalTo("test"));
}
@Test
public void sslWantsClientAuthenticationSucceedsWithoutClientCertificate()
throws Exception {
FileCopyUtils.copy("test",
new FileWriter(this.temporaryFolder.newFile("test.txt")));
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.setDocumentRoot(this.temporaryFolder.getRoot());
Ssl ssl = new Ssl();
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyStorePassword("secret");
ssl.setKeyPassword("password");
ssl.setClientAuth(ClientAuth.WANT);
ssl.setTrustStore("src/test/resources/test.jks");
ssl.setTrustStorePassword("secret");
factory.setSsl(ssl);
this.container = factory.getEmbeddedServletContainer();
this.container.start();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
new SSLContextBuilder().loadTrustMaterial(null,
new TrustSelfSignedStrategy()).build());
HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
assertThat(getResponse(getLocalUrl("https", "/test.txt"), requestFactory),
equalTo("test"));
}
protected String getLocalUrl(String resourcePath) {
return "http://localhost:" + this.container.getPort() + resourcePath;
return getLocalUrl("http", resourcePath);
}
protected String getLocalUrl(String scheme, String resourcePath) {
return scheme + "://localhost:" + this.container.getPort() + resourcePath;
}
protected String getLocalUrl(int port, String resourcePath) {
@@ -318,10 +552,27 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
}
}
protected String getResponse(String url,
HttpComponentsClientHttpRequestFactory requestFactory) throws IOException,
URISyntaxException {
ClientHttpResponse response = getClientResponse(url, requestFactory);
try {
return StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"));
}
finally {
response.close();
}
}
protected ClientHttpResponse getClientResponse(String url) throws IOException,
URISyntaxException {
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
ClientHttpRequest request = clientHttpRequestFactory.createRequest(new URI(url),
return getClientResponse(url, new HttpComponentsClientHttpRequestFactory());
}
protected ClientHttpResponse getClientResponse(String url,
HttpComponentsClientHttpRequestFactory requestFactory) throws IOException,
URISyntaxException {
ClientHttpRequest request = requestFactory.createRequest(new URI(url),
HttpMethod.GET);
ClientHttpResponse response = request.execute();
return response;

View File

@@ -21,11 +21,13 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ssl.SslConnector;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.junit.Test;
import org.mockito.InOrder;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests;
import org.springframework.boot.context.embedded.Ssl;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
@@ -39,6 +41,7 @@ import static org.mockito.Mockito.mock;
*
* @author Phillip Webb
* @author Dave Syer
* @author Andy Wilkinson
*/
public class JettyEmbeddedServletContainerFactoryTests extends
AbstractEmbeddedServletContainerFactoryTests {
@@ -94,6 +97,27 @@ public class JettyEmbeddedServletContainerFactoryTests extends
assertTimeout(factory, 60);
}
@Test
public void sslCiphersConfiguration() throws Exception {
Ssl ssl = new Ssl();
ssl.setKeyStore("src/test/resources/test.jks");
ssl.setKeyStorePassword("secret");
ssl.setKeyPassword("password");
ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" });
JettyEmbeddedServletContainerFactory factory = getFactory();
factory.setSsl(ssl);
this.container = factory.getEmbeddedServletContainer();
this.container.start();
JettyEmbeddedServletContainer jettyContainer = (JettyEmbeddedServletContainer) this.container;
SslConnector sslConnector = (SslConnector) jettyContainer.getServer()
.getConnectors()[0];
assertThat(sslConnector.getSslContextFactory().getIncludeCipherSuites(),
equalTo(new String[] { "ALPHA", "BRAVO", "CHARLIE" }));
}
private void assertTimeout(JettyEmbeddedServletContainerFactory factory, int expected) {
this.container = factory.getEmbeddedServletContainer();
JettyEmbeddedServletContainer jettyContainer = (JettyEmbeddedServletContainer) this.container;

View File

@@ -28,9 +28,11 @@ import org.apache.catalina.Service;
import org.apache.catalina.Valve;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.http11.AbstractHttp11JsseProtocol;
import org.junit.Test;
import org.mockito.InOrder;
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.util.SocketUtils;
import static org.hamcrest.Matchers.equalTo;
@@ -228,6 +230,24 @@ public class TomcatEmbeddedServletContainerFactoryTests extends
assertEquals("UTF-8", tomcat.getConnector().getURIEncoding());
}
@Test
public void sslCiphersConfiguration() throws Exception {
Ssl ssl = new Ssl();
ssl.setKeyStore("test.jks");
ssl.setKeyStorePassword("secret");
ssl.setCiphers(new String[] { "ALPHA", "BRAVO", "CHARLIE" });
TomcatEmbeddedServletContainerFactory factory = getFactory();
factory.setSsl(ssl);
Tomcat tomcat = getTomcat(factory);
Connector connector = tomcat.getConnector();
AbstractHttp11JsseProtocol<?> jsseProtocol = (AbstractHttp11JsseProtocol<?>) connector
.getProtocolHandler();
assertThat(jsseProtocol.getCiphers(), equalTo("ALPHA,BRAVO,CHARLIE"));
}
private void assertTimeout(TomcatEmbeddedServletContainerFactory factory, int expected) {
Tomcat tomcat = getTomcat(factory);
Context context = (Context) tomcat.getHost().findChildren()[0];

Binary file not shown.

Binary file not shown.