對于目前大部分Web應用來說,用戶認證基本上都由應用自身來完成。具體來說,Web應用利用自身存儲的用戶憑證(基本上是用戶名/密碼)與用戶提供的憑證進行比較進而確認其真實身份。但是這種由Web應用全權負責的認證方式會帶來如下兩個問題:
- 對于用戶來說,他們不得不針對不同的訪問Web應用提供不同的用戶憑證。如果這些憑證具有完全不同的密碼,我們沒有多少人能夠記得住,所以對于大部分整天暢游Internet的網友來說,我想他們在不同的網站注冊的帳號都會采用相同的密碼。密碼的共享必然帶來安全隱患,因為我們不能確定Web應用本身是否值得信任。“信任危機”來源于兩個方面:首先是對“人品”缺乏信任,我們不知道他們是否具有保護用戶敏感信息的意愿;其次是對“能力”缺乏信任,即我們不清楚他們是否有能力保護用戶的敏感信息,對于知名網站泄露用戶帳號信息的情況我們實在已經看的太多了。
- 對于Web應用的提供者來說,他們不得不對花費大量的時間、精力和資源來設計和開發自己的認證系統。在很多情況下,他們提供的是包含多個子系統的一整套解決方案,如果每個子系統均需要獨立的認證,那么投入的成本可想而知。所以他們希望能夠提供一個單一的“認證中心”來對整個“生態系統”提供認證,如果這個認證中心完全由第三方來免費提供,這無疑是最好的選擇。
上面提出的這兩點旨在說明一個問題:在Internet環境下,我們針對具體的Web應用設計獨立的認證系統往往是一件“吃力不討好”的事情。如果我們開發一個很小的Web應用,可能在實現用戶認證功能上面花費的成本比實現應用自身業務功能的成本更大,而且還會因為“信任危機”導致潛在的使用者不敢注冊。
在這種情況下,如果一個值得信任的第三方能夠提供一種免費的認證服務,那么這兩個問題均會迎刃而解。實際上目前這樣的第三方認證服務很多,而且他們的提供者均為值得信賴的IT服務提供商,比如微軟、Google、Facebook、Twitter,以及國內的新浪、騰訊、網易、人人和豆瓣等。就目前來說,這些第三方認證服務絕大部分均是基于OAuth 2.0設計的。
假設我有一件非常重要的文件存儲與于瑞士銀行的私有保險柜中,如果我需要委托某個人將他提取出來,除了將密碼告訴他之外別無他法,但是OAuth的目的卻是定義一種協議幫助資源的擁有者在不提供自身憑證的前提下授權第三方應用以他的名義存取受保護的資源。OAuth的全稱為“Open Authorization”,所以它是一個開放的協議,目前最新的版本為2.0。
OAuth 2.0的角色
獲得資源擁有者授權的第三方應用請求受保護的資源采用的不是授權者的憑證,所有一個被稱為Access Token的安全令牌。Access Token頒發過程會涉及到若干不同的“實體”,它們在這個過程中扮演者不同的角色,我們通過一個具體的場景來認識一下該過程中涉及到的幾種角色。
假設我們開發了一個集成了新浪微博認證的用于發布打折商品消息的App,經過用戶授權之后它可以調用新浪微博的Web API獲取用戶的電子郵箱地址并發布相應的打折消息。那么OAuth 2.0在這個場景中的作用就在于:用戶授權該應用以自己的名義調用新浪微博的Web API獲取自己的電子郵箱地址,整個過程涉及到如下4種角色。
- 資源擁有者(RO:Resource Owner):資源的擁有者也是授權者,如果它是一個“人”,一般就是指最終用戶。由于“資源”在這個場景中表示為用戶的電子郵箱地址,所以資源擁有者自然就是指最終用戶。
- 客戶端應用(Client):需要取得資源擁有者授權并最終訪問受保護資源的應用,對于我們的場景來說,就是我們創建的App。
- 資源服務器(Resource Server):最終承載資源的服務器,它一般體現為一個可被調用的Web API。對于我們提供的場景來說,客戶端通過調用新浪微博得Web API獲得用戶的電子郵箱地址,所以新浪微博就是資源服務器。
- 授權服務器(Authorization Server):它對用戶(一般情況下為資源擁有者)和客戶端應用實施認證,并在用戶授權的情況下向客戶端應用頒發Access Token。在我們提供的場景中,資源服務器和認證服務器合二為一,均為新浪微博。
客戶端憑證
一般來說,如果我們需要針對某種類型的第三方認證服務來開發我們自己的應用,我們需要向采用的認證服務提供商對該應用進行注冊,注冊成功之后會得到一個唯一標識該應用的ClientID和對應的ClientSecret(ClientID/ClientSecret是Windows Live Connect 的說法,Twitter和Facebook分別叫做ConsumerKey/ComsumerSecret和AppID/AppSecret。如果采用Google提供的OAuth 2.0 API,ClientID和ClientSecret是不需要的。)。它們相當于客戶端應用的憑證,認證服務利用它們來確定其真實身份。
接下來我們簡單演示一下如何為集成Windows Live Connect API的應用注冊一個ClientID。我們利用瀏覽器直接訪問https://account.live.com/developers/applications,如果當前用戶尚未登錄,瀏覽器會自動重定向到登錄窗口。當我們采用某個Windows Live帳號完成登錄之后,如下圖所示的“Windows Live Developer Center”頁面會呈現出來。
然后我們直接點擊“Create application”連接創建一個新的應用。我們只需要在顯示頁面的“Application name”文本框中為創建的應用設置一個名稱,同時在“Language”下拉框中選擇適合的語言。如下圖所示,我們為創建的應用取名為“AppDemo”。
當我們點擊“I accept”按鈕之后,應用被成功創建,相應的ClientID和ClientSecret也被生成出來。如下圖所示,ClientID和ClientSecret的值分別為“000000004410A2A5”和“HeIrRmGyHHtMqhBDJipfGiauQnSHtYUX”。除此之外,我們要需要設置重定向地址的域名,Windows Live向客戶端應用發送Access Token,以及其他數據采用的URI必須采用此域名,我們在下圖中指定的域名為“https://www.artech.com”。域名成功設置之后,點擊“Save”按鈕之后整個注冊工作結束。
處理流程
雖然OAuth 2.0具體采用的執行流程因采用不同類型的授權方式而有所不同,但是整個流程大體上由客戶端應用分別與資源擁有者、授權服務器和資源服務器進行的3輪交互來完成。這個過程基本上體現在下圖中,這被稱為經典的“Three-Legged OAuth”。
客戶端應用試圖獲取某個受保護的資源,首先得取得資源擁有者的授權,所以第一輪消息交換旨在讓客戶端獲得資源擁有者(即用戶)的授權。客戶端應用得到授權之后會得到一個被稱為Authorization Grant的對象,該對象實際上就是一個簡單的字符串用以表示成功取得了用戶的授權。接下來客戶端應用利用此Authorization Grant向授權服務取獲取用于訪問受保護資源所需的Access Token。在成功獲得Access Token之后,客戶端應用將其附加到針對資源服務器的請求中以獲取它所需要的目標資源。
Authorization Grant
OAuth 2.0的執行流程有點類似于的Kerberos認證:客戶端先獲得“認購權證”TGT(Ticket Granting Ticket),再利用TGT購買“入場券”ST(Service Ticket),最后憑借ST進行服務調用。對于OAuth 2.0來說,Access Token相當于Kerberos的ST,而Authorization Grant則與TGT具有相同的作用。
OAuth 2.0中的Authorization Grant代表一種中間憑證(Intermediate Credential),它代表了資源擁有者針對客戶端應用獲取目標資源的授權。OAuth 2.0定義了如下4種Authorization Grant類型,我們也可以利用定義其中的擴展機制定制其他類型的Authorization Grant。Authorization Grant的類型體現了授權采用的方式以及Access Token的獲取機制。
- Implicit:它代表一種“隱式”授權方式,即客戶端在取得資源擁有者(最終用戶)授權的情況下直接獲取Access Token,而不是間接地利用獲取的Authorization Grant來取得Access Token。換句話說,此種類型的Authorization Grant代表根本不需要Authorization Grant,那么上面介紹的“Three-Legged OAuth”變成了“Two-Legged OAuth”。
- Authorization Code:這是最為典型的Authorization Grant,客戶端應用在取得資源擁有者授權之后會從授權服務器得到一個Authorization Code作為Authorization Grant。在它獲取寄宿于資源服務器中的目標資源之前,需要利用此Authorization Code從授權服務器獲取Access Token。
- Resource Owner Password Credentials:資源擁有者的憑證直接作為獲取Access Token的Authorization Grant。這種Authorization Grant類型貌似與OAuth設計的初衷向違背(OAuth的主要目的在于讓客戶端應用在不需要提供資源擁有者憑證的情況下能夠以他的名義獲取受保護的資源),但是如果客戶端程序是值得被信任的,用戶(資源擁有者)向其提供自己的憑證也是可以接受的。
- Client Credentials:客戶端應用自身的憑證直接作為它用于獲取Access Token的Authorization Grant。這種類型的Authorization Grant適用于客戶端應用獲取屬于自己的資源,換句話說客戶端應用本身相當于資源的擁有者。
在本系列后續兩篇文章中我們將對Implicit和Authorization Code這兩種典型的Authorization Grant進行詳細介紹,敬請期待。
談談基于OAuth 2.0的第三方認證 [上篇]
談談基于OAuth 2.0的第三方認證 [中篇]
談談基于OAuth 2.0的第三方認證 [下篇]
文章列表