HTTP 身份驗證
HTTP 為訪問控制和認證提供了一個通用框架。本頁面介紹了 HTTP 認證框架,並展示瞭如何使用 HTTP “Basic” 方案限制對伺服器的訪問。
通用 HTTP 認證框架
RFC 7235 定義了 HTTP 認證框架,伺服器可以使用該框架質詢客戶端請求,客戶端也可以提供認證資訊。
質詢和響應流程如下所示:
- 伺服器向客戶端傳送
401(Unauthorized) 響應狀態,並提供如何使用WWW-Authenticate響應頭進行授權的資訊,該響應頭至少包含一個質詢。 - 希望向伺服器進行認證的客戶端可以透過包含帶有憑據的
Authorization請求頭來完成此操作。 - 通常,客戶端會向用戶顯示密碼提示,然後發出包含正確
Authorization頭的請求。
上述通用訊息流對於大多數(如果不是全部)認證方案都是相同的。但是,頭部中的實際資訊及其編碼方式會發生變化!
警告: 上圖中使用的“Basic”認證方案發送的憑據是經過編碼但未加密的。除非透過安全連線 (HTTPS/TLS) 進行交換,否則這將完全不安全。
代理認證
相同的質詢和響應機制也可用於代理認證。由於資源認證和代理認證可以共存,因此需要一套不同的頭部和狀態碼。在代理的情況下,質詢狀態碼是 407 (Proxy Authentication Required),Proxy-Authenticate 響應頭包含至少一個適用於代理的質詢,而 Proxy-Authorization 請求頭用於向代理伺服器提供憑據。
禁止訪問
如果(代理)伺服器收到無效憑據,它應該響應 401 Unauthorized 或 407 Proxy Authentication Required,使用者可以傳送新請求或替換 Authorization 頭部欄位。
如果(代理)伺服器收到有效但不足以訪問給定資源的憑據,伺服器應該響應 403 Forbidden 狀態碼。與 401 Unauthorized 或 407 Proxy Authentication Required 不同,該使用者無法進行認證,瀏覽器也不會提議再次嘗試。
在所有情況下,伺服器都可能傾向於返回 404 Not Found 狀態碼,以向沒有足夠許可權或未正確認證的使用者隱藏頁面的存在。
跨域影像的認證
一個潛在的安全漏洞(後來在瀏覽器中得到修復)是跨站影像的認證。從 Firefox 59 開始,從與當前文件不同來源載入的影像資源不再能夠觸發 HTTP 認證對話方塊 (Firefox bug 1423146),從而防止攻擊者能夠將任意影像嵌入到第三方頁面時竊取使用者憑據。
HTTP 認證的字元編碼
瀏覽器對使用者名稱和密碼使用 utf-8 編碼。
Firefox 曾經使用 ISO-8859-1,但為了與其他瀏覽器保持一致並避免 Firefox bug 1419658 中描述的潛在問題,已更改為 utf-8。
WWW-Authenticate 和 Proxy-Authenticate 頭部
WWW-Authenticate 和 Proxy-Authenticate 響應頭定義了應如何使用認證方法來獲取資源訪問許可權。它們必須指定使用哪種認證方案,以便希望授權的客戶端知道如何提供憑據。
這些頭部的語法如下:
WWW-Authenticate: <type> realm=<realm>
Proxy-Authenticate: <type> realm=<realm>
在此,<type> 是認證方案(“Basic”是最常見的方案,並在下面介紹)。realm 用於描述受保護區域或指示保護範圍。這可能是一條訊息,如“訪問暫存站點”或類似內容,以便使用者知道他們正在嘗試訪問哪個空間。
Authorization 和 Proxy-Authorization 頭部
Authorization 和 Proxy-Authorization 請求頭包含用於向(代理)伺服器認證使用者代理的憑據。在此,再次需要 <type>,後跟憑據,憑據可以根據所使用的認證方案進行編碼或加密。
Authorization: <type> <credentials>
Proxy-Authorization: <type> <credentials>
認證方案
通用的 HTTP 認證框架是許多認證方案的基礎。
IANA 維護著一份認證方案列表,但主機服務(如 Amazon AWS)也提供其他方案。
一些常見的認證方案包括:
- Basic
-
參見 RFC 7617,base64 編碼的憑據。更多資訊見下文。
- Bearer
-
參見 RFC 6750,用於訪問 OAuth 2.0 保護資源的承載令牌。
- Digest
-
參見 RFC 7616。Firefox 93 及更高版本支援 SHA-256 演算法。早期版本僅支援 MD5 雜湊(不推薦)。
- HOBA
-
參見 RFC 7486 第 3 節,HTTP Origin-Bound Authentication,基於數字簽名。
- Mutual
-
參見 RFC 8120
- Negotiate / NTLM
-
參見 RFC4559
- VAPID
-
參見 RFC 8292
- SCRAM
-
參見 RFC 7804
- AWS4-HMAC-SHA256
-
參見 AWS 文件。此方案用於 AWS3 伺服器認證。
方案在安全強度以及客戶端或伺服器軟體中的可用性方面可能有所不同。
“Basic”認證方案提供的安全性很差,但它得到廣泛支援且易於設定。下面將更詳細地介紹它。
基本認證方案
“Basic” HTTP 認證方案定義在 RFC 7617 中,它將憑據以使用者 ID/密碼對的形式傳輸,使用 base64 編碼。
基本認證的安全性
由於使用者 ID 和密碼以明文形式透過網路傳輸(儘管它是 base64 編碼的,但 base64 是一種可逆編碼),因此基本認證方案不安全。應將 HTTPS/TLS 與基本認證結合使用,以防止憑據被截獲。
此外,使用 HTTP 基本認證的網站特別容易受到跨站請求偽造 (CSRF) 攻擊,因為無論來源如何,使用者憑據都會在所有請求中傳送(這與基於 cookie 的憑據機制不同,因為 cookie 通常在跨站請求中被阻止)。網站在更改資料時應始終使用 POST 請求,幷包含 CSRF 令牌。
如果沒有這些安全增強功能,不應使用基本認證來保護敏感或有價值的資訊。
使用 Apache 和基本認證限制訪問
要在 Apache 伺服器上對目錄進行密碼保護,您需要一個 .htaccess 檔案和一個 .htpasswd 檔案。
.htaccess 檔案通常如下所示:
AuthType Basic
AuthName "Access to the staging site"
AuthUserFile /path/to/.htpasswd
Require valid-user
.htaccess 檔案引用了一個 .htpasswd 檔案,其中每行包含一個使用者名稱和一個密碼,用冒號 (:) 分隔。您無法看到實際的密碼,因為它們已被雜湊(在這種情況下使用基於 MD5 的雜湊)。請注意,如果您願意,可以為 .htpasswd 檔案命名不同,但請記住此檔案不應被任何人訪問。(Apache 通常配置為阻止訪問 .ht* 檔案)。
aladdin:$apr1$ZjTqBB3f$IF9gdYAGlMrs2fuINjHsz.
user2:$apr1$O04r.y2H$/vEkesPhVInBByJUkXitA/
使用 Nginx 和基本認證限制訪問
對於 Nginx,您需要指定要保護的位置,以及提供密碼保護區域名稱的 auth_basic 指令。然後,auth_basic_user_file 指令指向一個包含加密使用者憑據的 .htpasswd 檔案,就像上面的 Apache 示例一樣。
location /status {
auth_basic "Access to the staging site";
auth_basic_user_file /etc/apache2/.htpasswd;
}
使用 URL 中的憑據訪問
歷史上,一些網站允許您使用包含使用者名稱和密碼的編碼 URL 登入,如下所示:
https://username:password@www.example.com/
現代瀏覽器不再允許這種語法;在傳送請求之前,使用者名稱和密碼會從請求中剝離。