登入工程:現代 Web 應用的典型身份驗證需求

ThoughtWorks發表於2017-02-18

朋友就職於某大型網際網路公司。前不久,在閒聊間我問他日常工作的內容,他說他所在部門只負責一件事,即使用者與登入。

而他的具體工作則是為各個業務子網站提供友好的登入部件(Widget),從而統一整個網站群的登入體驗,同時也能令業務開發者不用花費額外的精力去關注使用者鑑權。這很有趣。

可以看出,在一個現代Web應用中,圍繞“登入”這一需求,儼然已經衍生出了一個新的工程。不管是我們面臨的需求,還是解決這些需求所運用的方法與工具,都已經超出了傳統Web應用身份驗證技術的範疇。

之前一篇文章中,我聊到傳統Web應用中的身份驗證技術,文章中列出的一些方法在之前很長一段時間內,為滿足大量的Web應用中身份驗證的需求提供了思路。在這篇文章裡,我將簡要介紹現代Web應用中幾種典型的身份驗證需求。

形式多樣的鑑權

考慮這樣一個場景:我們在電腦上登入了微軟賬號,電腦裡的“郵件”應用能夠自動同步郵件;我們登入Web版本的Outlook郵件服務,如果在郵件裡發現了重要的工作安排,將其新增到日曆中,很快電腦裡的“日曆”應用便能夠將這些日程顯示到Windows桌面上。

這個場景包含了多個鑑權過程。至少涉及了對Web版本Outlook服務的鑑權,也涉及了對離線版本的郵件應用的鑑權。要能夠支援同一批使用者既能夠在瀏覽器中登入,又能夠在移動端或本地應用登入(例如 Windows UWP 應用程式),就需要開發出能夠為兩種應用程式服務的鑑權體系。

在瀏覽器裡,我們通常假設使用者不信任瀏覽器,使用者通過與伺服器建立的臨時瀏覽器會話完成操作。會話開始時,使用者被重定向到特定頁面進行登入。登入完成後,使用者通過持續與伺服器互動來延續臨時會話的時長;一旦使用者一段時間不與伺服器互動,則他的會話很快就會過期(被伺服器強制登出)。

在移動應用中,情況有所不同。相對來說,安裝在移動裝置中的應用程式更受使用者信任,移動裝置本身的安全性也比瀏覽器更好。另一方面,將使用者重定向到一個網頁去登入的做法,並不能提供很好的使用者體驗——更重要的是,使用者在使用移動裝置時,時間是碎片化的。我們無法要求使用者必須在特定時間內完成操作,也就基本沒有會話的概念:我們需要找到一種能夠安全地在裝置中相對持久地儲存使用者憑據的方法,並且Web應用伺服器可能需要配合這種方式來完成鑑權。此外,移動裝置也不是絕對安全的,一旦裝置丟失,將給使用者帶來安全風險。所以需要在伺服器端提供一種機制來取消已登入裝置的訪問許可權。

(圖片來自:http://docs.identityserver.io/en/release/intro/big_picture.html)

方便使用者的多種登入方式

“輸入使用者名稱和密碼”作為標準的登入憑據被廣泛用於各種登入場景。不過,在Web應用、尤其是網際網路應用中,網站運營方越來越發現使用使用者名稱作為使用者標識確實給網站提供了便利,但對使用者來說卻並不是那麼有幫助:使用者很可能會忘記自己的使用者名稱。

使用者在使用不同網站的過程中,為了不忘記使用者名稱,只好使用相同的使用者名稱。如果恰好在某個網站遇到了該使用者名稱被佔用的情況,他就不得不臨時為這個網站擬一個新的使用者名稱,於是這個新使用者名稱很快就被忘記了。

在註冊時,越來越多的網站要求使用者提供電子郵箱地址或者手機號碼,有的網站還支援讓使用者以多種方式登入。比如,提供一種讓使用者在使用了一種方式註冊之後,還能繫結其他登入方式的功能。繫結完成之後,使用者可以選用他喜歡的登入方式。它隱含了一個網站與使用者共同的認知:聯絡方式的擁有者即為使用者本人,這種“從屬”關係能夠用於證實使用者的身份。當使用者下次在註冊新網站時遇到“郵件地址已被註冊”,或者“手機號已被註冊”的時候,基本可以確定自己曾經註冊過這個網站了。

(圖片來自:http://cargocollective.com/)

另外,登入過程中所支援的聯絡方式也呈現出多樣性。電子郵件服務在很多場景中逐漸被形式多樣的其他聯絡方式(比如手機、微信等)所取代,不少人根本沒有使用郵件的習慣,如果網站只提供郵箱註冊的途徑,有時候還會遭到那些不經常使用電子郵箱的使用者的反感。所以支援多種登入方式成為了很多網站的迫切需求。

雙因子鑑權:增強型登入過程

上一節中提到的“從屬”關係不光可以幫助使用者判斷自己是否註冊過一個網站,也可以幫助網站在忘記密碼時進行臨時認證,從而幫助使用者完成新密碼的設定。如果將這種從屬關係用於正常登入過程中的進一步驗證,就構成了雙因子鑑權。

雙因子鑑權要求使用者在登入過程中提供兩種形式不同的憑據,只有兩種驗證都成功才能繼續操作。現代化Web應用正在越來越多地使用這種增強型驗證方式來保護關鍵操作的安全性。例如,檢視和修改個人資訊,以及修改登入密碼等。

相信不少人還記得QQ密碼保護問題的機制,它使得盜號者即使盜取了QQ密碼,在不知道密碼保護問題的情況下,也無法修改現有密碼,讓賬號擁有者得以及時挽回損失。

雙因子的原理在於:兩種驗證因子性質不一致,冒用身份者同時獲得使用者這兩種資訊的機率十分低,從而能有效地保護賬號的安全。在QQ密碼保護的例子裡,密碼是一種每次登入時都會使用的固定文字、相對容易被盜;而密碼保護問題卻是不怎麼頻繁設定和更改的、隱祕的、個人關聯性極強的,不容易被盜。

(圖片來自:http://bit.ly/2kFc492)

現代化Web應用形式多樣,裝置種類繁多,場景複雜多變,而為了更好地保護使用者賬號的安全,很多應用開始將雙因子驗證作為登入過程中的鑑權步驟。而為了兼具安全和便利的特點,一些應用還要求運用一些優化策略以提高使用者體驗。比如,僅在使用者在新的裝置上登入、一段時間未登入之後的再次登入、在不常用的地點登入、修改聯絡資訊和密碼、轉移賬戶資產等關鍵操作時要求雙因子鑑權。

單點登入:還是需要精心設計

以前,一般只有大型網站、向使用者提供多種服務的時候(比如,網易公司運營網易門戶和網易郵箱等多種服務),才會有單點登入的迫切需求。但在現代化Web系統中,無論是從業務的多元化還是從架構的服務化來考慮,對服務的劃分都更細緻了。

從整個企業的業務模式(例如網易門戶和網易郵箱),到某項業務的具體流程(例如京東訂單和京東支付),再到某個流程中的具體步驟(例如簡訊驗證與支付扣款),“服務”這一概念越來越輕量級,於是人們不得不創造了“微服務”這個新的品類詞彙來擴充認知空間。

(圖片來自:http://cargocollective.com/)

在這整個的演變過程中,出於安全的需要,身份驗證的需求都是一直存在的,而且粒度越來越細。以前我們更關注使用者在多個子站點的統一登入體驗,現在我們還需要關注使用者在多個子流程中的統一登入體驗,以及在多個步驟中的統一登入體驗。而這些流程和步驟,很可能是獨立的Web系統(微服務),也有可能是一個使用者介面(獨立應用),還有可能是一個第三方系統(介面整合)。

可以說,單點登入的需求有增無減,只不過當開發者對這種模式已經習以為常,不再意識到這也是一個能夠專門討論的話題。

考慮與使用者系統整合,與業務系統分離

在討論安全時,分不開的兩個部分就是鑑權(Authentication)與授權(Authorization)。

鑑權的過程是向使用者發起質詢(Challenge),完成身份驗證工作。這正是登入所解決的問題。通常在登入系統成功識別使用者之後,就會將接下來的工作直接交給業務系統來完成。由於各個系統中的授權模型可能與業務形態有關係,因此登入與業務系統分離是很自然的設計。

在對安全要求更嚴格的企業或企業應用中,可能需要專門的訪問管理機制,不過,這樣的做法在網際網路應用中很少見。但在網際網路Web應用中,授權的範疇也包含一個很小的公有部分,是各個業務系統所共有的:即使用者狀態。我們希望在各業務子系統之間共享使用者狀態:使用者被鎖定之後,他在所有業務系統都被鎖定;使用者被登出之後,所有業務系統中有關他的資料都被封存。

(圖片來自:http://cargocollective.com/)

另外在多個業務系統中,還可能會共用使用者的基本資料和偏好設定等資料。比如,類似於郵件地址這樣的資料,它可以作為登入憑據,也可以作為一個基本的聯絡方式。如果使用者在一個子系統設定了偏好語言,其他子系統則直接使用該設定即可。這樣,開發一個“使用者”系統的想法也就應運而生了。由於與使用者的狀態等基礎資訊的關係很緊密,登入與使用者系統之間的整合是很自然的,將登入子系統直接作為這個使用者系統的一部分也不失為一種不錯的實踐。

與第三方整合:迎接更多使用者

“即得”是一個開放式文件共享應用,特點是“無需登入,即傳即得”,它利用長時間有效的Cookie來標識使用者,從而免除了人們使用應用之前必須註冊登入的繁瑣步驟。

這種做法的風險是,如果使用者有及時清理瀏覽器Cookie的習慣,那很可能導致使用者再一次登入時不再被識別。不過從這樣一個小例子中,卻容易看出登入的真正作用,就是Web應用識別使用者的過程,當下次同一個使用者再次使用時,Web應用就能夠知道“這就是上次來過的那個使用者”。

如果識別使用者這一需求能夠在不需要使用者註冊的前提下搞定,豈不兩全齊美?基於第三方身份提供方的介面來識別已經在其他平臺註冊的使用者,並將其轉化為自己應用中的使用者,這種方式完全可行,並且大量的開發人員已經有了豐富的實踐。

從 2010 年開始就有不少的大型網際網路公司開始推出開放平臺服務,讓第三方應用通過Web介面與這些網際網路服務互動,從而為他們提供更豐富多彩的功能。在這個過程中,一些應用不為這些平臺提供擴充套件,卻巧闢蹊徑地利用了這些開放平臺的身份識別介面來免除新使用者註冊的過程,從而為自己的產品快速匯入使用者。不少網站都提供“使用微博賬號登入”功能,相信讀者一定體驗過。

(圖片來自:http://bit.ly/2kFi3e8)

如果你的應用需要向第三方提供使用者,那麼我們的角色就由“從上下文中讀取使用者身份”變成了“向上下文中寫入使用者身份”了。如果你正好有過與各網際網路公司開放平臺的介面打交道的經歷,這時候,你就可以體驗一把提供開放、安全上下文的挑戰了。如果……你的平臺既希望讓其他平臺的使用者能夠平滑接入,又希望向其他平臺公開自己的使用者,那可能是另一番更有趣的挑戰。這個過程,也可以作為生物驗證之外的另一種間接消除密碼的實踐方式吧。

登入,現在實實在在地成為了一個獨立的工程。尤其在形態多樣的基於Web的應用,以及這些Web應用本身所依賴的各色後端服務快速生長的過程中,各種鑑權需求隨之而來。如何在保障各個環節中安全的同時,又為使用者提供良好的體驗,成為一個挑戰。

另外,個人資訊洩露的事件頻繁被曝光,它們導致的社會問題也開始被更多人關注和重視,作為IT系統支撐者的工程師們有責任瞭解事關安全的基礎知識,並掌握必要的技能去保護使用者資料和企業利益。

我會在接下來的文章中介紹解決典型登入需求的具體技術方案,以及相關領域的安全實踐常識。

相關文章