Spring Boot是否支持服务器名称指示(SNI)? [英] Does Spring Boot support Server Name Indication (SNI)?
问题描述
Spring Boot是否支持服务器名称指示(SNI)?具体来说,基于嵌入式请求的主机名,运行嵌入式Tomcat服务器并打包为可执行jar文件的Spring Boot(2.2.2.RELEASE)应用程序是否可以支持多个SSL证书/域?
Does Spring Boot support Server Name Indication (SNI)? Specifically, is it possible for a Spring Boot (2.2.2.RELEASE) application running an embedded Tomcat server and packaged as an executable jar file to support multiple SSL certificates/domains based on the hostname of the incoming request?
它似乎Tomcat支持SNI (自Tomcat 8.5),但是我不确定如何在Spring Boot应用程序中实现SNI.
It appears Tomcat supports SNI (as of Tomcat 8.5), but I'm not sure how to implement SNI in my Spring Boot app.
推荐答案
我能够使用以下配置来验证运行嵌入式Tomcat服务器的Spring Boot支持服务器名称指示(SNI):
I was able to verify that Spring Boot running an embedded Tomcat server supports Server Name Indication (SNI) using the following config:
application.properties
application.properties
abc.com.key-store=${user.dir}/abc.com.p12
xyz.com.key-store=${user.dir}/xyz.com.p12
ApplicationConfig.java
ApplicationConfig.java
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@Configuration
public class ApplicationConfig {
@Autowired
private Environment env;
@Bean
public ServletWebServerFactory servletContainer() throws Exception {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
// Override TomcatServletWebServerFactory methods (if needed)
};
// add SSL Connector
tomcat.addAdditionalTomcatConnectors(createSSLConnectorForMultipleHosts());
return tomcat;
}
private Connector createSSLConnectorForMultipleHosts() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
/**
* Tomcat 9.0.x server SSL Connector for multiple hosts
*
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true"
defaultSSLHostConfigName="*.abc.com">
<SSLHostConfig hostName="*.abc.com">
<Certificate certificateKeystoreFile="conf/abc.com.p12"
type="RSA" />
</SSLHostConfig>
<SSLHostConfig hostName="*.xyz.com">
<Certificate certificateKeystoreFile="conf/xyz.com.p12"
type="RSA" />
</SSLHostConfig>
</Connector>
*/
try {
connector.setScheme("https");
connector.setSecure(true);
connector.setPort(8443);
connector.setAttribute("SSLEnabled", "true");
connector.setAttribute("defaultSSLHostConfigName", "*.abc.com");
// *.abc.com
SSLHostConfig sslHostConfig = new SSLHostConfig();
sslHostConfig.setHostName("*.abc.com");
SSLHostConfigCertificate sslHostConfigCertificate = new SSLHostConfigCertificate(sslHostConfig, Type.RSA);
sslHostConfigCertificate.setCertificateKeystoreFile(env.getProperty("abc.com.key-store"));
sslHostConfig.addCertificate(sslHostConfigCertificate);
connector.addSslHostConfig(sslHostConfig);
// *.xyz.com
sslHostConfig = new SSLHostConfig();
sslHostConfig.setHostName("*.xyz.com");
sslHostConfigCertificate = new SSLHostConfigCertificate(sslHostConfig, Type.RSA);
sslHostConfigCertificate.setCertificateKeystoreFile(env.getProperty("xyz.com.key-store"));
sslHostConfig.addCertificate(sslHostConfigCertificate);
connector.addSslHostConfig(sslHostConfig);
return connector;
}
catch (Exception ex) {
throw new IllegalStateException("Exception creating SSL Connector: ", ex);
}
}
}
这篇关于Spring Boot是否支持服务器名称指示(SNI)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!