歡迎光臨
每天分享高質量文章

Spring Boot:HTTP和HTTPS支持

如今,企業級應用程式的常見場景是同時支持HTTP和HTTPS兩種協議,這篇文章考慮如何讓Spring Boot應用程式同時支持HTTP和HTTPS兩種協議。

準備

為了使用HTTPS連接器,需要生成一份Certificate keystore,用於加密和機密瀏覽器的SSL溝通。

如果你使用Unix或者Mac OS,可以通過下列命令: keytool-genkey-aliastomcat-keyalg RSA,在生成過程中可能需要你填入一些自己的信息,例如我的機器上反饋如下:

可以看出,執行完上述命令後在home目錄下多了一個新的.keystore檔案。

How Do

  • 首先在resources目錄下新建一個配置檔案tomcat.https.properties,用於存放HTTPS的配置信息;

  1. custom.tomcat.https.port=8443

  2. custom.tomcat.https.secure=true

  3. custom.tomcat.https.scheme=https

  4. custom.tomcat.https.ssl=true

  5. custom.tomcat.https.keystore=${user.home}/.keystore

  6. custom.tomcat.https.keystore-password=changeit

  • 然後在WebConfiguration類中創建一個靜態類TomcatSslConnectorProperties

  1. @ConfigurationProperties(prefix = "custom.tomcat.https")

  2. public static class TomcatSslConnectorProperties {

  3.    private Integer port;

  4.    private Boolean ssl = true;

  5.    private Boolean secure = true;

  6.    private String scheme = "https";

  7.    private File keystore;

  8.    private String keystorePassword;

  9.    //這裡為了節省空間,省略了getters和setters,讀者在實踐的時候要加上

  10.    public void configureConnector(Connector connector) {

  11.        if (port != null) {

  12.            connector.setPort(port);

  13.        }

  14.        if (secure != null) {

  15.            connector.setSecure(secure);

  16.        }

  17.        if (scheme != null) {

  18.            connector.setScheme(scheme);

  19.        }

  20.        if (ssl != null) {

  21.            connector.setProperty("SSLEnabled", ssl.toString());

  22.        }

  23.        if (keystore != null && keystore.exists()) {

  24.            connector.setProperty("keystoreFile", keystore.getAbsolutePath());

  25.            connector.setProperty("keystorePassword", keystorePassword);

  26.        }

  27.    }

  28. }

  • 通過註解加載tomcat.https.properties配置檔案,並與TomcatSslConnectorProperties系結,用註解修飾WebConfiguration類;

  1. @Configuration

  2. @PropertySource("classpath:/tomcat.https.properties")

  3. @EnableConfigurationProperties(WebConfiguration.TomcatSslConnectorProperties.class)

  4. public class WebConfiguration extends WebMvcConfigurerAdapter {...}

  • 在WebConfiguration類中創建EmbeddedServletContainerFactory型別的Srping bean,並用它添加之前創建的HTTPS連接器。

  1. @Bean

  2. public EmbeddedServletContainerFactory servletContainer(TomcatSslConnectorProperties properties) {

  3.    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();

  4.    tomcat.addAdditionalTomcatConnectors(createSslConnector(properties));

  5.    return tomcat;

  6. }

  7. private Connector createSslConnector(TomcatSslConnectorProperties properties) {

  8.    Connector connector = new Connector();

  9.    properties.configureConnector(connector);

  10.    return connector;

  11. }

  • 通過 mvn spring-boot:run啟動應用程式;

  • 在瀏覽器中訪問URL https://localhost:8443/internal/tomcat.https.properties

  • 在瀏覽器中訪問URL http://localhost:8080/internal/application.properties

分析

根據之前的文章和官方文件,Spring Boot已經對外開放了很多服務器配置,這些配置信息通過Spring Boot內部的ServerProperties類完成系結,若要參考Spring Boot的通用配置項,請點擊這裡

Spring Boot不支持通過application.properties同時配置HTTP連接器和HTTPS連接器。在官方文件70.8中提到一種方法,是將屬性值硬編碼在程式中。

因此我們這裡新建一個配置檔案tomcat.https.properties來實現,但是這並不符合“Spring Boot風格”,後續有可能應該會支持“通過application.properties同時配置HTTP連接器和HTTPS連接器”。我添加的TomcatSslConnectorProperties是模仿Spring Boot中的ServerProperties的使用機制實現的,這裡使用了自定義的屬性前綴custom.tomcat而沒有用現有的server.前綴,因為ServerProperties禁止在其他的配置檔案中使用該命名空間。

@ConfigurationProperties(prefix = "custom.tomcat.https")這個註解會讓Spring Boot自動將custom.tomcat.https開頭的屬性系結到TomcatSslConnectorProperties這個類的成員上(確保該類的getters和setters存在)。值得一提的是,在系結過程中Spring Boot會自動將屬性值轉換成合適的資料型別,例如custom.tomcat.https.keystore的值會自動系結到File物件keystore上。

使用@PropertySource("classpath:/tomcat.https.properties")來讓Spring Boot加載tomcat.https.properties檔案中的屬性。

使用@EnableConfigurationProperties(WebConfiguration.TomcatSslConnectorProperties.class)讓Spring Boot自動創建一個屬性物件,包含上述通過@PropertySource匯入的屬性。

在屬性值匯入記憶體,並構建好TomcatSslConnectorProperties實體後,需要創建一個EmbeddedServletContainerFactory型別的Spring bean,用於創建EmbeddedServletContainer。

通過createSslConnector方法可以構建一個包含了我們指定的屬性值的連接器,然後通過tomcat.addAdditionalTomcatConnectors(createSslConnector(properties));設置tomcat容器的HTTPS連接器。

參考資料

  1. 配置SSL

赞(0)

分享創造快樂

© 2021 知識星球   网站地图