Spring HTTP/HTTPS 通道安全

Spring Security
Remote
1
08:12 PM · Nov 29 ,2025

1. 概述

本教程演示瞭如何使用 Spring 的 Channel Security 功能,通過 HTTPS 來保護應用程序的登錄頁。

使用 HTTPS 進行身份驗證對於在傳輸過程中保護敏感數據完整性至關重要。

本文基於 Spring Security 登錄教程,增加了額外的安全層。我們重點介紹了通過編碼的 HTTPS 渠道提供登錄頁所需步驟。

2. 不啓用通道安全初始化

讓我們從之前文章中解釋的安全性配置開始。

該 Web 應用程序允許用户訪問:

  1. /anonymous.html ,無需身份驗證
  2. ,
  3. /login.html ,以及
  4. ,
  5. 其他頁面 (/homepage.html ) 在成功登錄後。

訪問受以下配置控制:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests() 
      .antMatchers("/anonymous*")
      .anonymous();

    http.authorizeRequests()
      .antMatchers("/login*")
      .permitAll();

    http.authorizeRequests()
      .anyRequest()
      .authenticated();

或者通過 XML:

<http use-expressions="true">
    <intercept-url pattern="/anonymous*" access="isAnonymous()"/>
    <intercept-url pattern="/login*" access="permitAll"/>
    <intercept-url pattern="/**" access="isAuthenticated()"/>
</http>

此時,登錄頁面位於:

http://localhost:8080/spring-security-login/login.html

用户可以通過 HTTP 進行身份驗證,但是由於密碼以明文形式發送,因此不安全。

3. HTTPS 服務器配置為了僅通過 HTTPS 提供登錄頁面,<strong>– SSL/TLS 支持。

請注意,您可以使用有效的證書,或者,僅用於測試目的,您可以生成自己的證書。

假設我們使用 Tomcat 並自行生成證書。我們首先需要創建一個 keystore,其中包含一個自簽名證書。

可以通過在終端中發出以下命令來生成 keystore:

keytool -genkey -alias tomcat -keyalg RSA -storepass changeit -keypass changeit -dname 'CN=tomcat'

這將創建一個私鑰和自簽名證書,位於您的用户配置文件中,在您的 home 文件夾中。

下一步是編輯 conf/server.xml,使其如下所示:

<Connector port="8080" protocol="HTTP/1.1"
   connectionTimeout="20000"
   redirectPort="8443" />

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
   maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
   clientAuth="false" sslProtocol="TLS"
   keystoreFile="${user.home}/.keystore" keystorePass="changeit" />

第二個 SSL/TLS <Connector> 標籤通常在配置文件中註釋掉,因此取消註釋並添加 keystore 信息就足夠了。 更多信息請參閲 Tomcat 的相關文檔

在 HTTPS 配置到位後,登錄頁面也可以通過以下 URL 提供:

https://localhost:8443/spring-security-login/login.html

除了 Tomcat 之外的 Web 服務器需要不同的配置,但它們可能相似。

4. 配置通道安全

到目前為止,我們已經能夠同時在 HTTP 和 HTTPS 下提供登錄頁面。本節將解釋如何強制使用 HTTPS。

為了強制登錄頁面使用 HTTPS,請修改您的安全配置,添加以下內容:

http.requiresChannel()
  .antMatchers("/login*").requiresSecure();

或者,將 requires-channel=”https” 屬性添加到您的 XML 配置中:

<intercept-url pattern="/login*" access="permitAll" requires-channel="https"/>

在此之後,用户只能通過 HTTPS 登錄。例如,將鏈接轉發到 /homepage.html 將繼承原始請求的協議,並在 HTTPS 下提供。

在單個 Web 應用程序中混合使用 HTTP 和 HTTPS 請求時,需要注意並進行進一步配置的額外方面。

5. Mixing HTTP and HTTPS

從安全角度來看,所有請求都通過 HTTPS 進行服務是一個好做法,也是一個值得追求的目標。

但是,如果使用 HTTPS 獨佔則不可行,我們可以配置 Spring 使用 HTTP,通過在配置中添加如下內容:

http.requiresChannel()
  .anyRequest().requiresInsecure();

或者在 XML 中添加 requires-channel=”http” 屬性:

<intercept‐url pattern="/**" access="isAuthenticated()" requires‐channel="http"/>

這會指示 Spring 使用 HTTP 進行所有請求,同時也會破壞原始的登錄機制。以下部分解釋了背後的原因。

5.1. A Custom Login Processing URL Over HTTPS

原始安全教程中的安全配置包含以下內容:

<form-login login-processing-url="/perform_login"/>

如果不強制 /perform_login 使用 HTTPS,則會發生一個到 HTTP 變體的重定向,從而丟失與原始請求發送的登錄信息

為了克服這個問題,我們需要配置 Spring 使用 HTTPS 進行處理 URL:

http.requiresChannel()
  .antMatchers("/login*", "/perform_login");

請注意 antMatchers 方法中傳遞的額外參數 /perform_login

XML 配置中的等效方法需要添加一個新的 <intercept-url> 元素到配置中:

<intercept-url pattern="/perform_login" requires-channel="https"/>

如果你的應用程序使用默認的 login-processing-url (它就是 /login),則不需要顯式配置,因為 /login* 模式已經涵蓋了它。

配置生效後,用户可以登錄,但無法訪問受保護的頁面,例如 /homepage.html,因為由於 Spring 的會話固定保護功能

5.2. Disabling session-fixation-protection

會話固定 是在切換 HTTP 和 HTTPS 時無法避免的問題。

默認情況下,Spring 在成功登錄後會創建一個新的 session-id。當用户加載 HTTPS 登錄頁面時,用户的 session-id cookie 會被標記為 secure。登錄後,上下文會切換到 HTTP,並且 cookie 會丟失,因為 HTTP 不安全。

為了避免這種情況,需要設置 session-fixation-protection none

http.sessionManagement()
  .sessionFixation()
  .none();

或者通過 XML:

<session-management session-fixation-protection="none"/>

禁用會話固定保護可能會有安全影響,因此,如果您擔心基於會話固定的攻擊,則需要權衡利弊。

6. 測試

應用所有這些配置更改後,在未登錄的情況下(使用 http://或https://)訪問/anonymous.html將通過HTTP重定向到該頁面。

直接打開其他頁面(如/homepage.html)應通過HTTPS重定向到登錄頁面,並在登錄後使用HTTP重定向回/homepage.html

7. 結論

在本教程中,我們學習瞭如何配置 Spring Web 應用程序,該應用程序通過 HTTP 進行通信,除了登錄機制之外。但是 現代 Web 應用程序幾乎總是應該只使用 HTTPS 作為其通信協議。降低安全級別或禁用安全功能(如 會話固定保護)從來都不是一個好主意。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.