登錄工程:現代 Web 應用中的身份驗證技術

在“登錄工程”的前兩篇文章分別介紹了傳統 Web 應用中的身份驗證技術,以及現代 Web 應用中的典型身份驗證需求,接下來是時候介紹適應于現代 Web 應用中的身份驗證實踐了。

安全議題不容忽視

登錄系統

首先,我們為登錄做一個簡要的定義,以令后續的講述更準確。之前的兩篇文章有意無意地混淆了“登錄”與“身份驗證”的說法,因為在本篇之前,對于不少“傳統 Web 應用”來說,通常完成了對身份的識別也就完成了整個登錄的過程,很少出現像企業應用環境中那樣復雜的情景和需求。但從之前的文章中我們看到,現代 Web 應用對身份驗證相關的需求已經向復雜化發展了。

我們有必要重新認識一下登錄系統。登錄指的是從識別用戶身份,到允許用戶訪問其權限相應的資源的過程。舉個例子,在網上買好了票之后去影院觀影的過程就是一個典型的登錄過程:我們先去取票機,輸入取票驗證碼取票;接著拿到票去影廳完檢票進入觀影。取票的過程即身份驗證,它能夠證明我們擁有這張票;而后面檢票的過程,則是授權我們訪問的過程。之所以要分成這兩個過程,最直接的原因還是業務形態本身的復雜性所決定的——如果觀景過程是免費匿名的,也就免去了這些過程。

在登錄的過程中,“鑒權”與“授權”是兩個最關鍵的過程。接下來要介紹的一些技術和實踐,也包含在這兩個方面中。雖然現代 Web 應用的登錄需求比較復雜,但只要處理好了鑒權和授權兩個方面,也就容易解決其余各個方面。在現代 Web 應用的登錄工程實踐中,需要結合傳統 Web 應用的典型實踐,以及一些新的思路,才能既解決好登錄需求,又能符合 Web 的輕量級架構思路。


解析常見的登錄場景

在簡單的 Web 系統中,典型的鑒權也就是要求用戶輸入并比對用戶名和密碼的過程;而授權則是確保會話 Cookie 存在。而在稍微復雜的 Web 系統中,則需要考慮多種鑒權方式,以及多種授權場景。在上一篇文章中所述的“多種登錄方式”和“雙因子鑒權”就是多種鑒權方式的例子。有經驗的人經常調侃說,只要理解了鑒權與授權,就能清晰地理解登錄系統了。不光如此,這也是設計安全的登錄系統的基礎所在。

下表是各種常見登錄過程中的場景與“鑒權”和“授權”的對應關系:

多種場景的登錄

從表中可以看出,鑒權的形式豐富多彩,有傳統的用戶名密碼對、客戶端證書,有人們越來越熟悉的第三方登錄、手機驗證,以及新興的掃碼和指紋等方式,它們都能用于對用戶的身份進行識別。在成功識別了用戶之后,在用戶訪問資源或執行操作之前,我們還需要對用戶的操作進行授權。

在一些特別簡單的情形中——用戶一經識別,就可以無限制地訪問資源、執行所有操作——系統直接對所有“已登錄的人”放行。比如高速公路收費站,只要車輛有合法的號牌即可放行,不需要給駕駛員發一張用于指示“允許行駛的方向或時間”的票據。除了這類特別簡單的情形之外,授權更多時候是比較復雜的工作。在單一的傳統 Web 應用中,授權的過程通常由會話 Cookie 來完成——只要服務器發現瀏覽器攜帶了對應的 Cookie,即允許用戶訪問資源、執行操作。而在瀏覽器之外,例如在 Web API 調用、移動應用和富 Web 應用等場景中,要提供安全又不失靈活的授權方式,就需要借助令牌技術。


令牌

令牌是一個在各種介紹登錄技術的文章中常被提及的概念,而且是在現代 Web 應用系統中非常關鍵的技術。令牌是一個非常簡單的概念,它指的是在用戶通過身份驗證之后,為用戶分配的一個臨時憑證。在系統內部,各個子系統只需要以統一的方式正確識別和處理這個憑證即可完成對用戶的訪問和操作進行授權。在上文所提到的例子中,電影票就是一個典型的令牌。影廳門口的工作人員只需要確認來客手持印有對應場次的電影票即視為合法訪問,而不需要理會客戶是從何種渠道取得了電影票(比如自行購買、朋友贈予等),電影票在本場次范圍內可以持續使用(比如可以中場出去休息等)、過期作廢。通過電影票這樣一個簡單的令牌機制,電影票的出售渠道可以豐富多樣,檢票人員的工作卻仍然簡單輕松。

從這個例子也可以看出令牌并非什么神奇的機制,只是一種很常見的做法。還記得第一篇文章中所述的“自包含的 Cookie”嗎?那實際上就是一個令牌而已,而且在令牌中寫有有關自己有效性的內容——正如一個電影票上會寫明場次與影廳編號一樣??梢姡?Web 安全系統中引入令牌的做法,有著與傳統場合一樣的妙用。在安全系統中,令牌經常用于包含安全上下文信息,例如被識別的用戶信息,令牌的頒發來源,令牌本身的有效期等。另外,在必要時可以由系統廢止令牌,在它下次被使用用于訪問、操作時,用戶被禁止。

由于令牌有這些特殊的妙用,因此安全行業對令牌的標準的制定工作一直沒有停止過。在現代化 Web 系統的演進過程中,流行的方式是傾向于選用基于 Web 技術的“簡單”的技術來代替相對復雜、重量級的技術。典型地,比如使用 JSON-RPC 或 REST 接口代替了 SOAP 格式的服務調用,用微服務架構代替了 SOA 架構等等。而適用于 Web 技術的令牌標準就是 Json Web Token(JWT),它規范了一種基于 JSON 的令牌的簡單格式,可用于安全地封裝安全上下文信息。


OAuth 2、Open ID Connect

OAuth 是一種開放的授權模型,它規定了一種供資源擁有方與消費方之間簡單又直觀的交互方法,即從消費方向資源擁有方發起使用 AccessToken(訪問令牌)簽名的 HTTP 請求。這種方式讓消費方應用在無需(也無法)獲得用戶憑據的情況下,只要用戶完成鑒權過程并同意消費方以自己的身份調用數據和操作,消費方就可以獲得能夠完成功能的訪問令牌。OAuth 簡單的流程和自由的編程模型讓它很好地滿足了開放平臺場景中授權第三方應用使用用戶數據的需求。不少互聯網公司建設開放平臺,將它們的用戶在其平臺上的數據以 API 的形式開放給第三方應用來使用,從而可以讓用戶享受更豐富的服務。

OAuth 在各個開放平臺的成功使用,令更多開發者了解到它,并被它簡單明確的流程所吸引。此外,OAuth 協議規定的是授權模型,并不規定訪問令牌的數據格式,也不限制在整個登錄過程中需要使用的鑒權方法。人們很快發現,只要對 OAuth 進行合適的利用即可將其用于各種自有系統中的場景。例如,將 Web 服務視作資源擁有方,而將富 Web 應用或者移動應用視作消費方應用,就與開放平臺的場景完全吻合。

另一個大量實踐的場景是基于 OAuth 的單點登錄。OAuth 并沒有對鑒權的部分做規定,也不要求在握手交互過程中包含用戶的身份信息,因此它并不適合作為單點登錄系統來使用。然而,由于 OAuth 的流程中隱含了鑒權的步驟,因而仍然有不少開發者將這一鑒權的步驟用作單點登錄系統,這也儼然衍生成為一種實踐模式。更有人將這個實踐進行了標準化,它就是 Open ID Connect——基于 OAuth 的身份上下文協議,通過它即可以 JWT 的形式安全地在多個應用中共享用戶身份。接下來,只要讓鑒權服務器支持較長的會話時間,就可以利用 OAuth 為多個業務系統提供單點登錄功能了。

我們還沒有討論 OAuth 對鑒權系統的影響。實際上,OAuth 對鑒權系統沒有影響,在它的框架內,只是假設已經存在了一種可用于識別用戶的有效機制,而這種機制具體是怎么工作的,OAuth 并不關心。因此我們既可以使用用戶名密碼(大多數開放平臺提供商都是這種方式),也可以使用掃碼登錄來識別用戶,更可以提供諸如“記住密碼”,或者雙因子驗證等其他功能。


匯總

上面羅列了大量術語和解釋,那么具體到一個典型的 Web 系統中,又應該如何對安全系統進行設計呢?綜合這些技術,從端到云,從 Web 門戶到內部服務,本文給出如下架構方案建議:

推薦為整個應用的所有系統、子系統都部署全程的 HTTPS,如果出于性能和成本考慮做不到,那么至少要保證在用戶或設備直接訪問的 Web 應用中全程使用 HTTPS。

用不同的系統分別用作身份和登錄,以及業務服務。當用戶登錄成功之后,使用 OpenID Connect 向業務系統頒發 JWT 格式的訪問令牌和身份信息。如果需要,登錄系統可以提供多種登錄方式,或者雙因子登錄等增強功能。作為安全令牌服務(STS),它還負責頒發、刷新、驗證和取消令牌的操作。在身份驗證的整個流程的每一個步驟,都使用 OAuth 及 JWT 中內置的機制驗證數據的來源方是可信的:登錄系統要申請登錄請求來自受認可的業務應用,而業務在獲得令牌之后也需要驗證令牌的有效性。

在 Web 頁面應用中,應該申請時效較短的令牌。將獲取到的令牌向客戶端頁面中以 httponly 的方式寫入會話 Cookie,以用于后續請求的授權;在后緒請求到達時,驗證請求中所攜帶的令牌,并延長其時效。基于 JWT 自包含的特性,輔以完備的簽名認證,Web 應用無需額外地維護會話狀態。

在富客戶端 Web 應用(單頁應用),或者移動端、客戶端應用中,可按照應用業務形態申請時效較長的令牌,或者用較短時效的令牌、配合專用的刷新令牌使用。

在 Web 應用的子系統之間,調用其他子服務時,可靈活使用“應用程序身份”(如果該服務完全不直接對用戶提供調用),或者將用戶傳入的令牌直接傳遞到受調用的服務的方式進行授權。各個業務系統可結合基于角色的訪問控制(RBAC)開發自有專用權限系統。


作為工程師,我們不免會考慮,既然登錄系統的需求可能如此復雜,而大家面臨的需求在很多時候又是如此類似,那么有沒有什么現成(Out of Box)的解決方案呢?自然是有的。IdentityServer 是一個完整的開發框架,提供了普通登錄到 OAuth 和 Open ID Connect 的完整實現;Open AM 是一個開源的單點登錄與訪問管理軟件平臺;而 Microsoft Azure AD 和 AWS IAM 則是公有云上的身份服務。幾乎在各個層次都有現成的方案可用。使用現成的產品和服務,能夠極大地縮減開發成本,尤其為創業團隊快速構建產品和靈活變化提供更有力的保障。

本文簡單解釋了登錄過程中所涉及的基本原理,以及現代 Web 應用中用于身份驗證的幾種實用技術,希望為您在開發身份驗證系統提供幫助?,F代 Web 應用的身份驗證需求多變,應用本身的結構也比傳統的 Web 應用更復雜,需要架構師在明確了登錄系統的基本原理的基礎之上,靈活利用各項技術的優勢,恰到好處地解決問題。

登錄工程的系列文章到此就全部結束了,歡迎就文章內容提供反饋。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容