SpringBoot配置SSL证书,支持https请求

2022-11-22 31点热度 0人点赞 0条评论

准备证书

首先我们准备好SSL证书,我们的证书一般是通过购买或者免费的例如LetsEncrypt获取到,一般下载下来主要会有这几个文件:

证书文件:some.example.crt 或者 cert.pem

私钥文件:some.example.key 或者 privkey.pem

这里需要将将PEM证书转换为p12以配置进Spring Boot。

先通过下列命令转换证书:

sudo openssl pkcs12 -export -in "你的证书文件路径" -inkey "你的私钥文件路径" -out "指定生成的p12证书文件路径"

例如:

sudo openssl pkcs12 -export -in "/etc/letsencrypt/live/some.example.com/cert.pem" -inkey "/etc/letsencrypt/live/some.example.com/privkey.pem" -out "/etc/letsencrypt/live/some.example.com/key.p12"

执行命令会让你设定p12证书的密码,自行设定并记住,待会配置需要用。

SpringBoot配置证书

Spring Boot 配置 SSL 很简单,只需要通过一系列的 server.ssl.* 参数即可完成配置,如下所示。

application.properties 配置文件参考配置:

server.port=8443
server.ssl.protocol=TLS
server.ssl.key-store=file:/etc/letsencrypt/live/some.example.com/key.p12
server.ssl.key-store-password=123456
server.ssl.key-store-type=PKCS12

这边只是提供了一个 SSL 单向验证的演示,更多 SSL 参数配置如下。

server.ssl.ciphers= # Supported SSL ciphers.
server.ssl.client-auth= # Whether client authentication is wanted ("want") or needed ("need"). Requires a trust store.
server.ssl.enabled= # Enable SSL support.
server.ssl.enabled-protocols= # Enabled SSL protocols.
server.ssl.key-alias= # Alias that identifies the key in the key store.
server.ssl.key-password= # Password used to access the key in the key store.
server.ssl.key-store= # Path to the key store that holds the SSL certificate (typically a jks file).
server.ssl.key-store-password= # Password used to access the key store.
server.ssl.key-store-provider= # Provider for the key store.
server.ssl.key-store-type= # Type of the key store.
server.ssl.protocol=TLS # SSL protocol to use.
server.ssl.trust-store= # Trust store that holds SSL certificates.
server.ssl.trust-store-password= # Password used to access the trust store.
server.ssl.trust-store-provider= # Provider for the trust store.
server.ssl.trust-store-type= # Type of the trust store.

参数对应的配置类:org.springframework.boot.web.server.Ssl

上面的例子配置后就能开启 HTTPS 了,默认的 HTTP 协议就不再支持了,Spring Boot 不支持以配置文件配置的方式同时支持 HTTP 和 HTTPS。

同时支持https和http

如果你需要同时支持 HTTP 和 HTTPS 这两个协议,就需要把另外一个协议用程序化的方式来配置。

因为通过程序的方式配置 HTTP 协议更加简单一点,所以,Spring Boot 推荐的做法是把 HTTPS 配置在配置文件,HTTP 通过程序来配置。

来,下面示例就是通过程序的方式来额外支持 HTTP 协议。

@SpringBootApplication
public class MyApplication {

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        tomcat.addAdditionalTomcatConnectors(createStandardConnector());
        return tomcat;
    }

    private Connector createStandardConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setPort(8080);
        return connector;
    }

    public static void main(String[] args) {
        SpringApplication.run(JavastackApplication.class, args);
    }

}

启动 Spring Boot 之后就会看到下面的同时支持两个协议日志。

Tomcat started on port(s): 8443 (https) 8080 (http) with context path '/'

如何将http重定向到https?

同样通过程序写在配置代码中:

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TomcatHttpConfig {

/**
 * 配置内置的servlet容器工厂为tomcat.
 * @return
 */
@Bean
public EmbeddedServletContainerFactory servletContainer() {
     TomcatEmbeddedServletContainerFactory
     tomcat = new TomcatEmbeddedServletContainerFactory() {

          @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);
          }
     };
     //添加连接配置,主要是http的配置信息.
     tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
          return tomcat;
     }

     /**
      * 配置一个http连接信息.
      * @return
      */
     private Connector initiateHttpConnector() {
          Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
          connector.setScheme("http");
          connector.setPort(8080);
          connector.setSecure(false);
          connector.setRedirectPort(443);
          return connector;
     }
}

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论