一文教你將 SpringBoot 網站升級為 HTTPS

rochy_he發表於2018-07-10

今年 2 月份,谷歌宣佈:7 月起,Chrome 瀏覽器的位址列將把所有 HTTP 標示為不安全網站!如今已經是 6 月底了,是時候將拋棄容易被第三方監控的 HTTP 擁抱 HTTPS 了。

下面就從 HTTPS 證書申請、網站 HTTPS 的配置、HTTP 重定向到 HTTPS 三個方面教你將一個 SpringBoot 網站升級為安全的 HTTPS。

證書申請

目前國內提供免費 HTTPS 證書的雲服務商並不多,一向不大方的騰訊這次倒是很大方,騰訊雲提供了免費的亞洲誠信品牌免費型 DV 版 SSL 證書,註冊認證過的使用者即可免費申請 20 個免費證書。

建立證書

選擇證書

首先你需要註冊認證騰訊雲,然後進入到 SSL證書 管理選單,點選申請證書按鈕,然後在彈框中選擇免費版DVSSL證書,點選確定按鈕。

選擇證書

完善域名資訊

然後填寫你的域名資訊,通用名稱即為你要申請證書的域名,申請郵箱填寫個人常用郵箱即可,如下圖所示:

填寫域名資訊

完成域名驗證

選擇DNS驗證後,會看到以下資訊:

DNS驗證

此時進入到域名提供商的後臺,新增一條解析即可:

新增TXT解析

最後回到證書驗證介面,點選驗證即可認證成功,認證成功後坐等稽核通過即可,一般稽核時間為幾分鐘到幾小時不等。

稽核完成後,就可以在證書列表介面下載證書了,下載的到的檔案是一個 ZIP 壓縮包,壓縮包裡面包含了各種常用的網站託管軟體所需的證書格式:

證書壓縮包內容

網站配置

拷貝金鑰

SpringBoot 預設使用 Tomcat 進行網站託管,因此從壓縮包中的 Tomcat 目錄將證書(檔案字尾為jks)拷貝到 SpringBoot 工程的 resources 目錄下即可:

拷貝證書到 resources 目錄

更新配置

證書拷貝完整後,開啟配置檔案 application.yml,然後修改網站的埠為 443key-store-password 可以在證書壓縮包的 Tomcat 資料夾下的文字檔案中找到,此外配置一下 SSL 證書的型別以及路徑等資訊即可:

server:
  address: 0.0.0.0
  port: 443
  ssl:
    enabled: true
    key-store: classpath:luooqi.com.jks
    key-store-password: xxxxxxxxxxxx
    key-store-type: JKS
複製程式碼

至此便可以啟動執行專案,可以在位址列輸入 https://yourdomain 即可訪問,在伺服器上釋出後可以看到如下效果:

認證釋出成功

將 HTTP 請求重定向到HTTPS

網站雖然升級到了 HTTPS,但是很多老使用者並不知情,當他們訪問舊版的 HTTP 地址時會發現網站已經無法訪問:

舊版 HTTP 網址無法正常訪問

因此最佳的做法是將 HTTP 重定向到 HTTPS,下面就教你如何通過程式碼實現。

新增 HTTP 埠配置

首先在配置檔案中新增自定義的 HTTP 埠配置:

http-port: 80
複製程式碼

建立重定向關係

新建一個配置類 HttpsConfiguration,在類中將配置檔案中自定義的 HTTP 埠和 HTTPS 的埠都注入進來,然後建立一個新的 Connector 來處理 HTTP 請求,同時設定 Connector 的埠為注入的 HTTP 埠,重定向埠(setRedirectPort)為新的 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.beans.factory.annotation.Value;
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;

@Configuration
public class HttpsConfiguration {
    @Value("${http-port}")
    private int port;

    @Value("${server.port}")
    private int sslPort;

    @Bean
    public ServletWebServerFactory 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(redirectConnector());
        return tomcat;
    }

    private Connector redirectConnector() {
        Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
        connector.setScheme("http");
        connector.setPort(port);
        connector.setSecure(false);
        connector.setRedirectPort(sslPort);
        return connector;
    }
}
複製程式碼

特別注意

上面程式碼中需要特別注意的是,TomcatServletWebServerFactory 必須要在其 postProcessContext 方法中新增 HTTP 的匹配範圍 addPattern("/*"),否則重定向無效。


Any Code,Code Any!

掃碼關注『AnyCode』,程式設計路上,一起前行。

一文教你將 SpringBoot 網站升級為 HTTPS

相關文章