談談基於OAuth 2.0的第三方認證 [上篇]
對於目前大部分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的第三方認證 [下篇]
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-25 15:04:51