Spring Boot是否支持服务器名称指示(SNI)? [英] Does Spring Boot support Server Name Indication (SNI)?

查看:201
本文介绍了Spring Boot是否支持服务器名称指示(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆