返回 导航

SpringBoot / Cloud

hangge.com

SpringBoot - Web项目使用SSL证书启用HTTPS教程

作者:hangge | 2021-01-26 08:10
    很早之前,Chrome 浏览器的地址栏就把所有 HTTP 标示为不安全网站。比如我在服务器上部署了一个 SpringBoot 开发的 Web 项目(端口 8080),使用 HTTP 访问的话浏览器会提示不安全:

    要将 SpringBoot 网站升级为 HTTPS,首先要申请 SSL 证书,然后在 SpringBoot 中配置证书。如果项目使用的 Nginx 的话,我们也可以在 Nginx 配置证书,这样 SpringBoot 这边就不用配置了。下面分别介绍这两种方式。

方式一:在 Nginx 配置证书

1,Nginx 的安装以及配置

    首先我们需要安装 Nginx 服务,并申请一个 SSL 证书,最后在 Nginx 中配置使用这个证书,具体步骤可以参考我之前写的文章:

2,配置 Nginx 转发

(1)首先编辑 nginx 配置文件:
vi /usr/local/nginx/conf/nginx.conf

(2)在 HTTPS server 部分设置反向代理,将请求转发到 Spring Boot 项目上:
location / {
    proxy_pass http://localhost:8080;
    proxy_redirect default;
}

(3)配置完成后,执行如下命令重启 Nginx
/usr/local/nginx/sbin/nginx -s reload

(4)使用浏览器访问 Nginx 服务,可以看到请求自动转发到 Spring Boot 项目上,并且前面也有小锁,说明 https 启用成功:
提示:由于我们通过 Nginx 来访问 Web 服务,那么原来的 8080 端口建议通过防火墙策略设置为不能从外部访问。

附:实现负载均衡

    如果部署了 Nginx 服务的话,我们还可以同时部署多个相同的 Web 项目,结合 Nginx 来实现负载均衡。具体的操作步骤可以参考我之前写的文章:

方式二:直接在 SpringBoot 中配置证书

1,申请证书

首先我们要申请一个 SSL 证书,具体参考我之前写的文章(只看申请证书部分,Nginx 的安装配置不用管):

2,生成的 Keystore 文件

(1)申请成功后,证书会保存在 /etc/letsencrypt/live/demo.hangge.com/ 下面,我们进入该文件夹:
原文:CentOS下自动申请、部署Let's Encrypt免费SSL证书教程(Nginx服务器)

(2)接下来,我们还需要用到 Linux 下的 opensslkeytool 工具,将 SSL 证书由 .pem 格式转换成 Tomcat 所支持的 .jks 格式。首先执行如下命令安装 openssl
yum -y install openssl

(3)接着执行如下命令将 .pem 格式的证书导出 .p12 格式的证书:
注意:导出时会要求我们设置一个密码,这里我设成 123456
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out hangge.p12

(4)接着在执行如下命令将证书由 .p12 格式转换成 .jks 格式:
提示:执行 openssl 命令导出 .p12 格式证书时会要求设置密钥,执行 keytool 命令时也有 3 处要写密钥,最简单的方式就是所有需要密钥的地方,都使用同一个,这样也不会搞混。
keytool -importkeystore -deststorepass '123456' -destkeypass '123456' -destkeystore hangge.jks -srckeystore hangge.p12 -srcstoretype PKCS12 -srcstorepass '123456'

(5)生成后会有条警告信息,把里面的建议命名复制出来执行一遍就好:
keytool -importkeystore -srckeystore hangge.jks -destkeystore hangge.jks -deststoretype pkcs12

(6)接下来的警告就不用管,只是提示信息(提示把原来的证书文件备份为了 .old 文件)

3,Spring Boot 配置

(1)首先将上面生成的 hangge.jks 证书文件添加到项目中,比如我这里放在 /src/main/resources/ssl 文件夹下:

(2)接着编辑项目的 application.properties 文件,添加如下配置:
提示:这里将服务器端口号设置成 443 端口,即 https 的默认访问端口,那么在进行 https 访问的时候可以不带端口号直接访问。如果端口被占用我们可以改成其他端口,比如 8443
server.port=443
server.ssl.enabled=true
# keystore 文件
server.ssl.key-store=classpath:ssl/hangge.jks
server.ssl.key-store-type=PKCS12
# keystore的密码
server.ssl.key-store-password=123456
server.port=443
server.ssl.enabled=true
# keystore 文件
server.ssl.key-store=/etc/letsencrypt/live/demo.hangge.com/hangge.jks
server.ssl.key-store-type=PKCS12
# keystore的密码
server.ssl.key-store-password=123456

(3)光有 HTTPS 肯定还不够,因为用户有可能继续使用 HTTP 来访问我们的网站。接下来还需要在 Spring Boot 启动类中注入下面两个 Bean,实现 HTTP 自动转向 HTTPS 的功能。
@SpringBootApplication
public class SpringbootApplication {

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

  @Bean
  public Connector connector(){
    Connector connector=new Connector("org.apache.coyote.http11.Http11NioProtocol");
    connector.setScheme("http");
    connector.setPort(80);
    connector.setSecure(false);
    connector.setRedirectPort(443);
    return connector;
  }

  @Bean
  public TomcatServletWebServerFactory tomcatServletWebServerFactory(Connector connector){
    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(connector);
    return tomcat;
  }
}

(4)重新部署启动服务,使用浏览器访问 http://demo.hangge.com,如果正常跳转到 https://demo.hangge.com,并且地址栏有个小锁图标则说明 https 配置成功了:
评论

全部评论(0)

回到顶部