Springboot配置SSL(https)

SpringBoot可以通过在application.properties或application.yml配置文件中配置各种server.ssl.*属性来声明性使用SSL(https)
首先在配置文件里配置

#配置https的端口
server.port=8443
#配置https的证书
server.ssl.key-store=classpath:tomcat.pkcs12
#证书的密码(在生成证书的时候会指定一个密码)
server.ssl.key-store-password=123456
#执行证书的类型
server.ssl.key-store-type=pkcs12

如果使用了上面的配置就表示springboot应用程序不再在端口8080上支持HTTP连接请求,SpringBoot不能通过配置application.properties来实现既支持HTTP连接又支持HTTPS连接,这是做不到的,如果要同时支持HTTP和HTTPS,则需要以编程方式配置其中的一个,建议使用application.properties文件来配置HTTPS,以编程方式配置HTTP,这是比较容易的方法;

SpringBoot支持配置https具体步骤:

1.1、生成证书,可以使自签名证书(平时测试的时候)或者从SSL证书授权中心购买证书(上线);

平时生成证书进行测试的话,有两种生成证书的方式:
A. 利用Openssl工具生成证书
通过openssl来生成,如果linux中没有安装openssl,需要安装一下,执行:
yum install openssl openssl-devel -y
1、#生成一个RSA密钥 (私钥)
openssl genrsa -out server.key 2048
2、#生成一个证书请求
openssl req -new -key server.key -out server.csr -subj “/C=CN/ST=Beijing/L=Beijing/O=power Inc./OU=Web Security/CN=power.com”
3、#自己签发证书
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
字段解读
C字段:Country,单位所在国家,为两位数的国家缩写,如:CN 表示中国;
ST 字段:State/Province,单位所在州或省;
L 字段:Locality,单位所在城市/或县区;
O 字段:Organization,此网站的单位名称;
OU 字段:Organization Unit,下属部门名称,也常常用于显示其他证书相关信息,如证书类型,证书产品名称或身份验证类型或验证内容等;
CN 字段:Common Name,网站的域名

转换为pkcs12格式(因为在Java中使用证书,需要转换一下格式)
openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.p12
或者
openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.pkcs12

把生成的server.pkcs12粘贴到resources目录下
这时候修改一下配置文件

#SSL,配置https的端口
server.port=8443
#配置https的证书
server.ssl.key-store=classpath:server.pkcs12
#证书的密码(在生成证书的时候会指定一个密码)
server.ssl.key-store-password=123456
#执行证书的类型
server.ssl.key-store-type=pkcs12

B. 利用JDK工具生成证书
keytool是jdk的工具,安装好jdk可以找到,用于生成jks专有格式
keytool -genkey -keyalg RSA -keystore tomcat.jks
(RSA为一种加密算法)
转换为pkcs12行业标准格式:(生成这个格式后java才识别)
keytool -importkeystore -srckeystore tomcat.jks -destkeystore tomcat.pkcs12 -deststoretype pkcs12

转换为jks格式(因为在Java中使用证书,需要转换一下格式,jks是java独有的)
在jdk1.8的bin目录下运行cmd命令:
keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12 -deststoretype jks
生成后依然实行粘贴并改配置文件的操作

证书生成后我们可以验证下jks是否包含了完整的证书链:
keytool -list -v -keystore server.jks
keytool -list -v -keystore server.pkcs12

SpringBoot同时支持https和http

在配置类里配置一个bean

/**
     * 编程方式实现springboot的http
     *
     * @return
     */
    @Bean
    public TomcatServletWebServerFactory servletContainer() {
        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);
            }
        };
        tomcat.addAdditionalTomcatConnectors(createHttpConnector());
        return tomcat;
    }

    /**
     * 创建http连接器
     *
     * @return
     */
    private Connector createHttpConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        // http端口
        connector.setPort(8080);
        connector.setSecure(false);
        // https端口
        connector.setRedirectPort(8443);
        return connector;
    }

这样在以http访问时也会跳转到https路径
如果不想要跳转,则注释掉
connector.setRedirectPort(8443);
以及

//安全约束
  SecurityConstraint securityConstraint = new SecurityConstraint();
  securityConstraint.setUserConstraint("CONFIDENTIAL");
  SecurityCollection collection = new SecurityCollection();
  collection.addPattern("/*");
  securityConstraint.addCollection(collection);
  context.addConstraint(securityConstraint);

注意:不能在代码中即配置http又配置https(如果已经在配置文件中写过一种配置方法)

集群下,每个服务器都要放证书文件
注销掉配置文件相关代码,同时在代码里配置https

/**
     * 编程方式实现springboot的https
     *
     * @return
     */
    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> containerCustomizer() {
        return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
            @Override
            public void customize(ConfigurableWebServerFactory container) {
                Ssl ssl = new Ssl();
                //服务器私钥和证书
                String path = MyConfig.class.getClassLoader().getResource("server.jks").getPath();
                ssl.setKeyStore(path);
                ssl.setKeyStorePassword("123456");
                ssl.setKeyStoreType("jks"); //通过配置文件读进来 @Value("${}")
                container.setSsl(ssl);
                container.setPort(8443);
            }
        };
    }
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐