帳號密碼驗證
在 Web 領域裡,要在公開服務上對一般的使用者做身分驗證,最常見的實作即帳號密碼驗證。包括 Google、Facebook、AppleID 等,都是使用帳號密碼驗證。
這裡的「一般的使用者」,指的是網頁服務的使用者,通常 HTTP 的任務會交由 User Agent 來代為發送 HTTP 請求與接受回應並處理。
Access Authentication Framework
此方法最一開始是 1997 年定義在 RFC 2069,後來 1999 年在 RFC 2617 重新定義,接著 2014 年 RFC 7235 再一次重新定義。
這裡有個有趣的地方在,先前在簡介 HTTP 協定時,曾提到 HTTP/1.1 在 RFC 上的定義是從 RFC 2068 到 RFC 2616,最後才是 RFC 7230 ~ RFC 7235。而 Access Authentication Framework 的定義一直都是跟隨著在 HTTP 協定之後,這也可以看得出身分驗證在 HTTP 被設計的時候就已經有在考慮了。
它的流程如下:
@startuml |
它的好處是,因為它跟隨著最開始的 HTTP 協定一起發布,因此理論上支援度是最高的。只是有許多未考慮的情境,如它是明文傳輸,因此需要 TLS 避免使用者憑證(credentials)外泄等;另外,驗證完成後,憑證一直會保存到瀏覽器關閉,換言之,登出的唯一手段就是關閉瀏覽器。這對想繼續維持登入狀態,或想登出但又不想關閉瀏覽器來說,都非常麻煩。
即便這個方法有些安全性問題,但支援度高的關係,一般內部信任網域的服務常會採用這個方法。
HTTP + HTML Form-based Authentication
基於 HTTP + HTML 表單驗證這個方法只有在維基百科裡提到,IETF 並沒有特別定義這個方法,但是它是目前最常用的方法,主因是因為 Access Authentication Framework 的規範只實現在瀏覽器的彈出視窗裡,並且只有使用者和密碼兩個欄位,客製化畫面呈現或流程是完全沒有方法的。只是在使用 HTTP + HTML 表單驗證時,必須要了解相關的安全注意事項。
HTTP + HTML 表單驗證的流程描述如下。
- 未驗證的使用者想使用服務,服務會回傳 HTML 網頁,裡面包含了帶有使用者憑證資訊(如帳號、密碼等)輸入與提交按鈕的表單
- 使用者填寫憑證資訊,並點擊提交按鈕;同時 User Agent 將表單資訊傳送給 Web 服務器
- Web 服務器回傳驗證結果
流程圖如下:
@startuml |
表單的內容範例如下:
<form method="POST" action="/login"> |
安全注意事項
使用這個方法,首要的問題依然是:HTTP 是明文傳輸,需要 TLS 避免攻擊者竊取傳輸內容。
再來如一開始所說,雖然 HTML 或 HTTP 都有標準可以依循,但兩者結合一起做身分驗證這個方法並沒有標準化。因此正常來說,使用者或 User Agent 並不知道今天連線的 Web 服務器是如何做身分驗證的。
最後,這個技術非常容易實現網路釣魚,因為它建立在「使用者準確地訪問正確的網址」上,來避免使用者憑證外泄,但事實上使用者通常辦不到,這同時也是為何網路釣魚是一個很常見的安全漏洞。
因 HTTP 協定是無狀態的,因此如果沒有 Cookie 的協助,會變成每次都要重打帳號密碼。但使用 Cookie 的同時,記得詳閱 Cookie 的安全隱患,以確保系統沒有漏洞讓攻擊者可以趁虛而入。
參考資料
- RFC 2068 - Hypertext Transfer Protocol – HTTP/1.1
- RFC 2069 - An Extension to HTTP : Digest Access Authentication
- RFC 2616 - Hypertext Transfer Protocol – HTTP/1.1
- RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication
- RFC 7235 - Hypertext Transfer Protocol (HTTP/1.1): Authentication
- HTTP+HTML form-based authentication - 維基百科
- 網路釣魚 - 維基百科