下面列出了org.springframework.boot.web.servlet.server.ServletWebServerFactory#org.apache.tomcat.util.net.SSLHostConfig 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
protected Map<String,List<String>> getConnectorCiphers(StringManager smClient) {
Map<String,List<String>> result = new HashMap<>();
Connector connectors[] = getConnectors();
for (Connector connector : connectors) {
if (Boolean.TRUE.equals(connector.getProperty("SSLEnabled"))) {
SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs();
for (SSLHostConfig sslHostConfig : sslHostConfigs) {
String name = connector.toString() + "-" + sslHostConfig.getHostName();
/* Add cipher list, keep order but remove duplicates */
result.put(name, new ArrayList<>(new LinkedHashSet<>(
Arrays.asList(sslHostConfig.getEnabledCiphers()))));
}
} else {
ArrayList<String> cipherList = new ArrayList<>(1);
cipherList.add(smClient.getString("managerServlet.notSslConnector"));
result.put(connector.toString(), cipherList);
}
}
return result;
}
@Override
public void begin(String namespace, String name, Attributes attributes) throws Exception {
SSLHostConfig sslHostConfig = (SSLHostConfig)digester.peek();
Type type;
String typeValue = attributes.getValue("type");
if (typeValue == null || typeValue.length() == 0) {
type = Type.UNDEFINED;
} else {
type = Type.valueOf(typeValue);
}
SSLHostConfigCertificate certificate = new SSLHostConfigCertificate(sslHostConfig, type);
digester.push(certificate);
}
/**
* Store nested SSLHostConfigCertificate elements.
* {@inheritDoc}
*/
@Override
public void storeChildren(PrintWriter aWriter, int indent, Object aSSLHostConfig,
StoreDescription parentDesc) throws Exception {
if (aSSLHostConfig instanceof SSLHostConfig) {
SSLHostConfig sslHostConfig = (SSLHostConfig) aSSLHostConfig;
// Store nested <SSLHostConfigCertificate> elements
SSLHostConfigCertificate[] hostConfigsCertificates = sslHostConfig.getCertificates().toArray(new SSLHostConfigCertificate[0]);
// Remove a possible default UNDEFINED certificate
if (hostConfigsCertificates.length > 1) {
ArrayList<SSLHostConfigCertificate> certificates = new ArrayList<>();
for (SSLHostConfigCertificate certificate : hostConfigsCertificates) {
if (Type.UNDEFINED != certificate.getType()) {
certificates.add(certificate);
}
}
hostConfigsCertificates = certificates.toArray(new SSLHostConfigCertificate[0]);
}
storeElementArray(aWriter, indent, hostConfigsCertificates);
// Store nested <OpenSSLConf> element
OpenSSLConf openSslConf = sslHostConfig.getOpenSslConf();
storeElement(aWriter, indent, openSslConf);
}
}
@Override
public void storeChildren(PrintWriter aWriter, int indent, Object aConnector,
StoreDescription parentDesc) throws Exception {
if (aConnector instanceof Connector) {
Connector connector = (Connector) aConnector;
// Store nested <Listener> elements
LifecycleListener listeners[] = connector.findLifecycleListeners();
storeElementArray(aWriter, indent, listeners);
// Store nested <UpgradeProtocol> elements
UpgradeProtocol[] upgradeProtocols = connector.findUpgradeProtocols();
storeElementArray(aWriter, indent, upgradeProtocols);
if (Boolean.TRUE.equals(connector.getProperty("SSLEnabled"))) {
// Store nested <SSLHostConfig> elements
SSLHostConfig[] hostConfigs = connector.findSslHostConfigs();
storeElementArray(aWriter, indent, hostConfigs);
}
}
}
@Test
public void testOpenSSLConfCmdCipher() throws Exception {
log.info("Found OpenSSL version 0x" + Integer.toHexString(OPENSSL_VERSION));
SSLHostConfig sslHostConfig;
if (hasTLS13()) {
// Ensure TLSv1.3 ciphers aren't returned
sslHostConfig = initOpenSSLConfCmd("CipherString", ENABLED_CIPHER,
"CipherSuites", "");
} else {
sslHostConfig = initOpenSSLConfCmd("CipherString", ENABLED_CIPHER);
}
String[] ciphers = sslHostConfig.getEnabledCiphers();
Assert.assertThat("Wrong HostConfig ciphers", ciphers,
CoreMatchers.is(EXPECTED_CIPHERS));
ciphers = SSLContext.getCiphers(sslHostConfig.getOpenSslContext().longValue());
Assert.assertThat("Wrong native SSL context ciphers", ciphers,
CoreMatchers.is(EXPECTED_CIPHERS));
}
protected void sslReload(PrintWriter writer, String tlsHostName, StringManager smClient) {
Connector connectors[] = getConnectors();
boolean found = false;
for (Connector connector : connectors) {
if (Boolean.TRUE.equals(connector.getProperty("SSLEnabled"))) {
ProtocolHandler protocol = connector.getProtocolHandler();
if (protocol instanceof AbstractHttp11Protocol<?>) {
AbstractHttp11Protocol<?> http11Protoocol = (AbstractHttp11Protocol<?>) protocol;
if (tlsHostName == null || tlsHostName.length() == 0) {
found = true;
http11Protoocol.reloadSslHostConfigs();
} else {
SSLHostConfig[] sslHostConfigs = http11Protoocol.findSslHostConfigs();
for (SSLHostConfig sslHostConfig : sslHostConfigs) {
if (sslHostConfig.getHostName().equalsIgnoreCase(tlsHostName)) {
found = true;
http11Protoocol.reloadSslHostConfig(tlsHostName);
}
}
}
}
}
}
if (found) {
if (tlsHostName == null || tlsHostName.length() == 0) {
writer.println(smClient.getString("managerServlet.sslReloadAll"));
} else {
writer.println(smClient.getString("managerServlet.sslReload", tlsHostName));
}
} else {
writer.println(smClient.getString("managerServlet.sslReloadFail"));
}
}
@Override
public SSLUtil getSSLUtil(SSLHostConfigCertificate certificate) {
SSLHostConfig sslHostConfig = certificate.getSSLHostConfig();
if (sslHostConfig.getProtocols().size() == 1 &&
sslHostConfig.getProtocols().contains(PROPERTY_VALUE)) {
if (JreCompat.isJre8Available()) {
sslHostConfig.setProtocols(Constants.SSL_PROTO_TLSv1_2);
} else {
sslHostConfig.setProtocols(Constants.SSL_PROTO_TLSv1);
}
return super.getSSLUtil(certificate);
} else {
return null;
}
}
public SSLHostConfig initOpenSSLConfCmd(String... commands) throws Exception {
Assert.assertNotNull(commands);
Assert.assertTrue("Invalid length", commands.length % 2 == 0);
Tomcat tomcat = getTomcatInstance();
TesterSupport.initSsl(tomcat);
String protocol = tomcat.getConnector().getProtocolHandlerClassName();
// The tests are only supported for APR and OpenSSL
if (!protocol.contains("Apr")) {
String sslImplementation = String.valueOf(
tomcat.getConnector().getProperty("sslImplementationName"));
Assume.assumeTrue("This test is only for OpenSSL based SSL connectors",
sslImplementation.contains("openssl"));
}
OpenSSLConf conf = new OpenSSLConf();
for (int i = 0; i < commands.length;) {
OpenSSLConfCmd cmd = new OpenSSLConfCmd();
cmd.setName(commands[i++]);
cmd.setValue(commands[i++]);
conf.addCmd(cmd);
}
SSLHostConfig[] sslHostConfigs = tomcat.getConnector().
getProtocolHandler().findSslHostConfigs();
Assert.assertEquals("Wrong SSLHostConfigCount", 1, sslHostConfigs.length);
sslHostConfigs[0].setOpenSslConf(conf);
tomcat.start();
sslHostConfigs = tomcat.getConnector().getProtocolHandler().findSslHostConfigs();
Assert.assertEquals("Wrong SSLHostConfigCount", 1, sslHostConfigs.length);
return sslHostConfigs[0];
}
@Test
public void run() throws IOException {
try (final Meecrowave CONTAINER = new Meecrowave(new Builder() {{
randomHttpsPort();
setSkipHttp(true);
includePackages("org.apache.meecrowave.tests.ssl");
setSsl(true);
setDefaultSSLHostConfigName("localhost");
setTomcatNoJmx(false);
setProperties(p);
}}).bake()) {
final String confPath = CONTAINER.getBase().getCanonicalPath() + "/conf/";
SSLHostConfig[] sslHostConfigs = CONTAINER.getTomcat().getService().findConnectors()[0].findSslHostConfigs();
assertEquals(3, sslHostConfigs.length);
assertTrue(isFilesSame(confPath + keyStorePath1, sslHostConfigs[0].getCertificateKeystoreFile()));
assertEquals("JKS", sslHostConfigs[0].getCertificateKeystoreType());
assertEquals("meecrowave", sslHostConfigs[0].getCertificateKeystorePassword());
assertEquals("meecrowave", sslHostConfigs[0].getCertificateKeyAlias());
assertEquals("localhost", sslHostConfigs[0].getHostName());
assertTrue(isFilesSame(confPath + "meecrowave_trust.jks", sslHostConfigs[0].getTruststoreFile()));
assertEquals("meecrowave", sslHostConfigs[0].getTruststorePassword());
assertTrue(isFilesSame(confPath + keyStorePath2, sslHostConfigs[1].getCertificateKeystoreFile()));
assertEquals("JKS", sslHostConfigs[1].getCertificateKeystoreType());
assertEquals("meecrowave", sslHostConfigs[1].getCertificateKeystorePassword());
assertEquals("meecrowave", sslHostConfigs[1].getCertificateKeyAlias());
assertEquals("meecrowave-localhost", sslHostConfigs[1].getHostName());
assertEquals(2, sslHostConfigs[1].getProtocols().size());
assertEquals("meecrowave.apache.org", sslHostConfigs[2].getHostName());
assertTrue(isFilesSame(confPath + "meecrowave.key.pem", sslHostConfigs[2].getCertificateKeyFile()));
assertTrue(isFilesSame(confPath + "meecrowave.cert.pem", sslHostConfigs[2].getCertificateFile()));
assertTrue(isFilesSame(confPath + "ca-chain.cert.pem", sslHostConfigs[2].getCertificateChainFile()));
assertEquals("TLSv1.2", sslHostConfigs[2].getProtocols().toArray()[0]);
assertEquals("Hello", TestSetup.callJaxrsService(CONTAINER.getConfiguration().getHttpsPort()));
}
}
private List<SSLHostConfig> buildSslHostConfig() {
final List<SSLHostConfig> sslHostConfigs = new ArrayList<>();
// Configures default SSLHostConfig
final ObjectRecipe defaultSslHostConfig = newRecipe(SSLHostConfig.class.getName());
for (final String key : configuration.getProperties().stringPropertyNames()) {
if (key.startsWith("connector.sslhostconfig.") && key.split("\\.").length == 3) {
final String substring = key.substring("connector.sslhostconfig.".length());
defaultSslHostConfig.setProperty(substring, configuration.getProperties().getProperty(key));
}
}
if (!defaultSslHostConfig.getProperties().isEmpty()) {
sslHostConfigs.add(SSLHostConfig.class.cast(defaultSslHostConfig.create()));
}
// Allows to add N Multiple SSLHostConfig elements not including the default one.
final Collection<Integer> itemNumbers = configuration.getProperties().stringPropertyNames()
.stream()
.filter(key -> (key.startsWith("connector.sslhostconfig.") && key.split("\\.").length == 4))
.map(key -> Integer.parseInt(key.split("\\.")[2]))
.collect(toSet());
itemNumbers.stream().sorted().forEach(itemNumber -> {
final ObjectRecipe recipe = newRecipe(SSLHostConfig.class.getName());
final String prefix = "connector.sslhostconfig." + itemNumber + '.';
configuration.getProperties().stringPropertyNames().stream()
.filter(k -> k.startsWith(prefix))
.forEach(key -> {
final String keyName = key.split("\\.")[3];
recipe.setProperty(keyName, configuration.getProperties().getProperty(key));
});
if (!recipe.getProperties().isEmpty()) {
final SSLHostConfig sslHostConfig = SSLHostConfig.class.cast(recipe.create());
sslHostConfigs.add(sslHostConfig);
new LogFacade(Meecrowave.class.getName())
.info("Created SSLHostConfig #" + itemNumber + " (" + sslHostConfig.getHostName() + ")");
}
});
return sslHostConfigs;
}
public void addSslHostConfig(SSLHostConfig sslHostConfig) {
protocolHandler.addSslHostConfig(sslHostConfig);
}
public SSLHostConfig[] findSslHostConfigs() {
return protocolHandler.findSslHostConfigs();
}
@Override
public void addSslHostConfig(SSLHostConfig sslHostConfig) {
getLog().warn(sm.getString("ajpprotocol.noSSL", sslHostConfig.getHostName()));
}
@Override
public SSLHostConfig[] findSslHostConfigs() {
return new SSLHostConfig[0];
}
@Override
public void addSslHostConfig(SSLHostConfig sslHostConfig) {
getEndpoint().addSslHostConfig(sslHostConfig);
}
@Override
public SSLHostConfig[] findSslHostConfigs() {
return getEndpoint().findSslHostConfigs();
}
public void addCertificate(SSLHostConfigCertificate certificate) throws Exception {
// Load Server key and certificate
if (certificate.getCertificateFile() != null) {
// Set certificate
SSLContext.setCertificate(ctx,
SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()),
SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()),
certificate.getCertificateKeyPassword(), getCertificateIndex(certificate));
// Set certificate chain file
SSLContext.setCertificateChainFile(ctx,
SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), false);
// Set revocation
SSLContext.setCARevocation(ctx,
SSLHostConfig.adjustRelativePath(
sslHostConfig.getCertificateRevocationListFile()),
SSLHostConfig.adjustRelativePath(
sslHostConfig.getCertificateRevocationListPath()));
} else {
String alias = certificate.getCertificateKeyAlias();
X509KeyManager x509KeyManager = certificate.getCertificateKeyManager();
if (alias == null) {
alias = "tomcat";
}
X509Certificate[] chain = x509KeyManager.getCertificateChain(alias);
if (chain == null) {
alias = findAlias(x509KeyManager, certificate);
chain = x509KeyManager.getCertificateChain(alias);
}
PrivateKey key = x509KeyManager.getPrivateKey(alias);
StringBuilder sb = new StringBuilder(BEGIN_KEY);
String encoded = BASE64_ENCODER.encodeToString(key.getEncoded());
if (encoded.endsWith("\n")) {
encoded = encoded.substring(0, encoded.length() - 1);
}
sb.append(encoded);
sb.append(END_KEY);
SSLContext.setCertificateRaw(ctx, chain[0].getEncoded(),
sb.toString().getBytes(StandardCharsets.US_ASCII),
getCertificateIndex(certificate));
for (int i = 1; i < chain.length; i++) {
SSLContext.addChainCertificateRaw(ctx, chain[i].getEncoded());
}
}
}
/**
* Bean: ServletWebServerFactory.
* Creates a dual port Tomcat, listening both in an http port and an https port. The http port simply redirects to the https one.
*
* @return TomcatServletWebServerFactory.
*/
@Bean
public ServletWebServerFactory servletWebServerFactory() {
// Check if there is dual port configuration.
if (serverProperties.getInternalHttpPort() == null
|| serverProperties.getExternalHttpPort() == null
|| serverProperties.getInternalHttpsPort() == null
|| serverProperties.getExternalHttpsPort() == null
|| serverProperties.getPort().equals(serverProperties.getInternalHttpPort())
|| !serverProperties.getPort().equals(serverProperties.getInternalHttpsPort())) {
return new TomcatServletWebServerFactory();
}
// Set TLS ECDH offered curves.
if (!StringUtils.isEmpty(sslProperties.getEcdhCurves()))
System.setProperty(JdkProperty.TLS_ECDH_CURVES.getPropertyName(), sslProperties.getEcdhCurves());
// Enable TLS OCSP stapling.
if (sslProperties.getEnableOcspStapling() != null)
System.setProperty(JdkProperty.TLS_ENABLE_OCSP_STAPLING.getPropertyName(), sslProperties.getEnableOcspStapling().toString());
// Create the https Tomcat.
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(
Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
// Customize the https connector.
tomcat.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(
Connector connector) {
SSLHostConfig sslHostConfig = connector.findSslHostConfigs()[0];
sslHostConfig.setHonorCipherOrder(true);
}
});
// Add the http connector with a redirection to the https port.
Connector httpConnector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
httpConnector.setScheme("http");
httpConnector.setPort(serverProperties.getInternalHttpPort());
httpConnector.setSecure(false);
httpConnector.setRedirectPort(serverProperties.getExternalHttpsPort());
tomcat.addAdditionalTomcatConnectors(httpConnector);
return tomcat;
}
@Override
public void addSslHostConfig(SSLHostConfig sslHostConfig) {}
@Override
@SuppressWarnings("ZeroLengthArrayAllocation")
public SSLHostConfig[] findSslHostConfigs() {
return new SSLHostConfig[0];
}
private Connector makeConnector() {
Connector connector = new Connector(Http11Nio2Protocol.class.getName());
if (keystoreFile == null) {
// HTTP connector
connector.setPort(port);
connector.setSecure(false);
connector.setScheme("http");
} else {
// HTTPS connector
connector.setPort(securePort);
connector.setSecure(true);
connector.setScheme("https");
connector.setAttribute("SSLEnabled", "true");
SSLHostConfig sslHostConfig = new SSLHostConfig();
SSLHostConfigCertificate cert =
new SSLHostConfigCertificate(sslHostConfig, SSLHostConfigCertificate.Type.RSA);
cert.setCertificateKeystoreFile(keystoreFile.toAbsolutePath().toString());
cert.setCertificateKeystorePassword(keystorePassword);
cert.setCertificateKeyAlias(keyAlias);
sslHostConfig.addCertificate(cert);
connector.addSslHostConfig(sslHostConfig);
}
connector.addUpgradeProtocol(new Http2Protocol());
// Keep quiet about the server type
connector.setXpoweredBy(false);
// Basic tuning params:
connector.setAttribute("maxThreads", 400);
connector.setAttribute("acceptCount", 50);
//connector.setAttribute("connectionTimeout", 2000);
connector.setAttribute("maxKeepAliveRequests", 100);
// Avoid running out of ephemeral ports under heavy load?
connector.setAttribute("socket.soReuseAddress", true);
connector.setMaxPostSize(0);
connector.setAttribute("disableUploadTimeout", false);
// Allow long URLs
connector.setAttribute("maxHttpHeaderSize", 65536);
// Enable response compression
connector.setAttribute("compression", "on");
// Defaults are text/html,text/xml,text/plain,text/css
connector.setAttribute("compressableMimeType", "text/html,text/xml,text/plain,text/css,text/csv,application/json");
return connector;
}
public void addSslHostConfig(SSLHostConfig sslHostConfig);
public SSLHostConfig[] findSslHostConfigs();