1. 程式人生 > >Spring Boot 支援 Https 有那麼難嗎?

Spring Boot 支援 Https 有那麼難嗎?

https 現在已經越來越普及了,特別是做一些小程式或者公眾號開發的時候,https 基本上都是剛需了。

不過一個 https 證書還是挺費錢的,個人開發者可以在各個雲服務提供商那裡申請一個免費的證書。我印象中有效期一年,可以申請 20 個。

今天要和大家聊的是在 Spring Boot 專案中,如何開啟 https 配置,為我們的介面保駕護航。

https 簡介

我們先來看看什麼是 https,根據 wikipedia 上的介紹:

超文字傳輸安全協議(HyperText Transfer Protocol Secure),縮寫:HTTPS;常稱為 HTTP over TLS、HTTP over SSL 或 HTTP Secure)是一種通過計算機網路進行安全通訊的傳輸協議。HTTPS 經由 HTTP 進行通訊,但利用 SSL/TLS 來加密資料包。HTTPS 開發的主要目的,是提供對網站伺服器的身份認證,保護交換資料的隱私與完整性。這個協議由網景公司(Netscape)在 1994 年首次提出,隨後擴充套件到網際網路上。

歷史上,HTTPS 連線經常用於網路上的交易支付和企業資訊系統中敏感資訊的傳輸。在 2000 年代末至 2010 年代初,HTTPS 開始廣泛使用,以確保各型別的網頁真實,保護賬戶和保持使用者通訊,身份和網路瀏覽的私密性。

另外,還有一種安全超文字傳輸協議(S-HTTP),也是 HTTP 安全傳輸的一種實現,但是 HTTPS 的廣泛應用而成為事實上的 HTTP 安全傳輸實現,S-HTTP並沒有得到廣泛支援。

準備工作

首先我們需要有一個 https 證書,我們可以從各個雲服務廠商處申請一個免費的,不過自己做實驗沒有必要這麼麻煩,我們可以直接藉助 Java 自帶的 JDK 管理工具 keytool 來生成一個免費的 https 證書。

進入到 %JAVVA_HOME%\bin 目錄下,執行如下命令生成一個數字證書:

keytool -genkey -alias tomcathttps -keyalg RSA -keysize 2048  -keystore D:\javaboy.p12 -validity 365

命令含義如下:

  • genkey 表示要建立一個新的金鑰。
  • alias 表示 keystore 的別名。
  • keyalg 表示使用的加密演算法是 RSA ,一種非對稱加密演算法。
  • keysize 表示金鑰的長度。
  • keystore 表示生成的金鑰存放位置。
  • validity 表示金鑰的有效時間,單位為天。

具體生成過程如下圖:

命令執行完成後 ,我們在 D 盤目錄下會看到一個名為 javaboy.p12 的檔案。如下圖:

有了這個檔案之後,我們的準備工作就算是 OK 了。

引入 https

接下來我們需要在專案中引入 https。

將上面生成的 javaboy.p12 拷貝到 Spring Boot 專案的 resources 目錄下。然後在 application.properties 中新增如下配置:

server.ssl.key-store=classpath:javaboy.p12
server.ssl.key-alias=tomcathttps
server.ssl.key-store-password=111111

其中:

  • key-store表示金鑰檔名。
  • key-alias表示金鑰別名。
  • key-store-password就是在cmd命令執行過程中輸入的密碼。

配置完成後,就可以啟動 Spring Boot 專案了,此時如果我們直接使用 Http 協議來訪問介面,就會看到如下錯誤:

改用 https 來訪問 ,結果如下:

這是因為我們自己生成的 https 證書不被瀏覽器認可,不過沒關係,我們直接點選繼續訪問就可以了(實際專案中只需要更換一個被瀏覽器認可的 https 證書即可)。

請求轉發

考慮到 Spring Boot 不支援同時啟動 HTTP 和 HTTPS ,為了解決這個問題,我們這裡可以配置一個請求轉發,當用戶發起 HTTP 呼叫時,自動轉發到 HTTPS 上。

具體配置如下:

@Configuration
public class TomcatConfig {
    @Bean
    TomcatServletWebServerFactory tomcatServletWebServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint constraint = new SecurityConstraint();
                constraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                constraint.addCollection(collection);
                context.addConstraint(constraint);
            }
        };
        factory.addAdditionalTomcatConnectors(createTomcatConnector());
        return factory;
    }
    private Connector createTomcatConnector() {
        Connector connector = new
                Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8081);
        connector.setSecure(false);
        connector.setRedirectPort(8080);
        return connector;
    }
}

在這裡,我們配置了 Http 的請求埠為 8081,所有來自 8081 的請求,將被自動重定向到 8080 這個 https 的埠上。

如此之後,我們再去訪問 http 請求,就會自動重定向到 https。

結語

Spring Boot 中加入 https 其實很方便。如果你使用了 nginx 或者 tomcat 的話,https 也可以發非常方便的配置,從各個雲服務廠商處申請到 https 證書之後,官方都會有一個詳細的配置教程,一般照著做,就不會錯了。

關注公眾號【江南一點雨】,專注於 Spring Boot+微服務以及前後端分離等全棧技術,定期視訊教程分享,關注後回覆 Java ,領取鬆哥為你精心準備的 Java 乾貨!