最近在看《OAuth 2.0實戰》(作者:賈斯廷.里徹和安東尼奧.桑索)這本書,打算邊學邊以博客的形式進行總結,博客命名為OAuth2系列($number),其中的number為博客順序。
一、什么是OAuth 2.0
OAuth 2.0是一個授權協議,它允許軟件應用代表(而不是充當)資源擁有者去訪問資源擁有者的資源,應用向資源擁有者請求授權,然后取得令牌(token),並用它來訪問資源。
以上是文章中對OAuth 2.0的解釋,仔細剖析,可以得到以下幾個關鍵的信息:
- 軟件應用
- 代表資源擁有者
- 訪問資源擁有者的資源
- 應用向資源擁有者請求授權
其實一句簡單的話中包含了OAuth中最關鍵的三種角色:客戶端(應用)、資源擁有者、受保護的資源。而OAuth設計的目的就是:
讓用戶通過OAuth將他們在受保護資源上的部分權限委托給客戶端應用,使客戶端應用代表他們執行操作
這個委托的過程就是授權的過程,所以自然而然地引入了第四種角色:授權服務器。
二、OAuth中的四種角色
舉一個例子:假設你是京東的一個程序員,最近手里負責了五六個項目,有點顧不過來,於是你招了一個外包同學,希望委托他幫你負責其中的三個項目,你要求他今天入職並將那三個項目的代碼pull下來熟悉熟悉,從他入職到拉下代碼需要以下幾個步驟:
第一步:他告訴你他到公司樓下了,進京東大廈需要你來證明;
第二步:你需要在公司內部的辦公軟件上申請一個訪客碼給他,首先你用自己的erp賬號登錄了辦公軟件,申請成功並發送了一個訪客碼給外包同學;
第三步:外包同學拿着訪客碼進入京東大廈,辦理了入職流程,同時人事小姐姐給他在內部辦公軟件上開通了一個erp賬號;
第四步:他找到你,並用自己的erp賬號登錄了git地址,從git上clone了你給他開通權限的三個項目的代碼;
以上這個例子就發生的身邊,仔細想來其實跟OAuth 2.0的授權流程很相似,其中包含了OAuth中最重要的四種角色:客戶端、資源擁有者、授權服務器、受保護的資源
1、客戶端
客戶端是代表資源擁有者訪問受保護資源的軟件,即上面例子中的外包同學,你委托他幫你負責三個項目。
2、資源擁有者
資源擁有者是有權將訪問權限授權給客戶端的主體,即上面例子中的你,你擁有6個項目代碼的讀寫權限。
3、受保護的資源
受保護的資源是能夠通過http服務器進行訪問,訪問時需要OAuth下發的令牌(token),即上面例子中的代碼庫;
4、授權服務器
授權服務器是一個HTTP服務器,它在OAuth系統中充當中央組件。授權服務器對資源擁有者和客戶端進行身份認證,讓資源擁有者向客戶端授權、為客戶端頒發令牌,即上面例子中的公司辦公軟件。以上流程可以用下面的圖來表示:
上圖詮釋了外包同學入職並clone你給他開通權限的代碼的整個過程,圖中的數字每一步數字代表的含義如下:
- 你委托外包同學負責你的三個項目
- 外包同學告訴你進京東大廈需要你的證明,於是你需要去申請一個訪客碼
- 你用自己的erp賬號登錄內部辦公軟件
- 在內部軟件上申請了訪客碼
- 你告訴外包同學訪客碼已經發到他的手機上了
- 外包同學拿着訪客碼進入京東大廈辦理入職流程
- HR給他在內部辦公軟件上開通了一個erp賬號
- 外包同學到達你所在的辦公區,坐在工位上,打開電腦使用自己的erp賬號訪問你給他開通權限的代碼庫地址
- 外包同學將代碼clone到了自己的電腦上
三、OAuth 2.0的授權過程
上一節中外包的例子基本可以解釋OAuth 2.0的授權過程,但是存在一個問題就是:當他的ERP過期之后,如果還要繼續在京東做項目,假設他想再進入京東大廈,是不是就要重新走一次訪客碼的過程,這個例子可能不是很恰當,但是對應到OAuth中,就是令牌(token)失效。一般為了保證token的安全性,token都有有效期,過了有效期之后如果想繼續訪問受保護的資源,可能還要重新走一遍授權流程,這個流程對客戶端來說是比較繁瑣的一種體驗,為了提升這種體驗,OAuth 2.0提供了一種刷新token機制,即在第一次返回token的同時會返回一個刷新token用於換取新的token,這個刷新token本身並不能訪問受保護的資源,但是客戶端可以用它換取新的可以訪問受保護資源的有效token。完整的授權流程如下UML圖所示:
1.資源擁有者訪問客戶端應用,並表明他希望客戶端代表自己去使用某一個受保護的資源
2.當客戶端發現需要獲取一個新的OAuth訪問令牌時,他會將資源擁有者重定向至授權服務器,並附帶一個授權請求,表示他要向資源擁有者請求一些權限
3.授權服務器會要求用戶進行身份認證。這一步對確認資源擁有者的身份以及能向客戶端授予哪些權限來說至關重要。
- 用戶身份認證直接在用戶(瀏覽器)與授權服務器之間進行,這個過程對客戶端應用不可見。這一特性避免了用戶將自己的憑據暴露給客戶端應用,對抗這種反模式正是發明OAuth的原因。
- 因為資源擁有者是通過瀏覽器與授權服務器進行交互,所以也是通過瀏覽器來完成身份認證,所以就會有很多身份認證技術可以用戶用戶的身份認證流程。OAuth沒用規定使用哪種身份認證技術,授權服務器可以自由選擇,例如用戶名密碼、加密證書、安全令牌、聯合單點登錄等。
4. 用戶向客戶端應用授權
客戶端可以在授權請求中指明其想要獲取哪些權限,授權服務器可以允許用戶拒絕一部分獲取全部權限范圍,也可以讓用戶批准或拒絕整個授權請求。此外,很多授權服務器允許將授權決策保留下來以便以后使用,這樣可以在以后同一個客戶端訪問相同的授權時,無需提示用 戶是否授權,授權服務器甚至可以通過客戶端白名單、黑名單等策略來否決用戶的否決。
5.授權服務器將用戶重定向回客戶端應用
在授權碼模式中,重定向時回攜帶授權服務器生成的授權碼code和客戶端請求授權時的state,其中授權碼code是一次性憑據,標識用戶授權決策的結果,客戶端會在接受到請求之后解析該參數以獲取授權碼,同時驗證state是否與前一步的請求是否匹配。
6.瀏覽器請求重定向地址中的客戶端地址
7.客戶端通過授權碼向授權服務器申請令牌
客戶端通過發送一個POST請求,以表單形式傳遞參數,並在header中設置client_id和client_secret,這兩個參數一般都會加密后以Authorization:Basic 的形式發送。授權服務器接受該請求,需要進行如下驗證,驗證通過才能頒發token:
- 驗證客戶端憑據(即client_id)以確定是哪個客戶端的授權請求
- 從請求參數中獲取授權碼code,並獲取關於該授權碼的信息,包括發起初始授權請求的是哪個客戶端?執行授權的是哪個用戶?授權的內容是什么?
- 如果該授權碼有效且未被使用過,而且發起該請求的客戶端與最初發起授權請求的客戶端一致,則授權服務器會生成一個新的訪問令牌兵返回給客戶端
8.客戶端解析令牌響應,並從中獲取token
令牌響應中一般會包含令牌的類型token_type,訪問令牌access_token,還會包含一個刷新令牌refresh_token,還有一些附加的信息,比如令牌的權限范圍和過期時間等,客戶端可以將令牌存放在一個安全的地方,以便在用戶不在場時使用。
9.客戶端通過令牌token來訪問受保護的資源
10.客戶端成功獲取到受保護的資源
11.當令牌過期之后,客戶端可以通過令牌響應結果中返回的refresh_token,向授權服務器換取新的token,而不需要重新進行一次授權流程。
12.授權服務器返回新的token供用戶繼續訪問受保護的資源
以上就是基於授權碼模式的OAuth 2.0的完整授權流程。
四、OAuth中的組件
OAuth中除了四種主要角色之外,還有其他幾種機制,如:令牌、授權范圍、授權許可
1、訪問令牌(access_token)
訪問令牌,簡稱令牌,由授權服務區頒發給客戶端,表示客戶端已經被授予它所請求的權限,OAuth並沒有定義令牌本身的格式和內容,它總代表着:客戶端請求的訪問權限、對客戶端授予權限的資源擁有者、被授予的權,且令牌對於客戶端是不透明的,客戶端並不知道也不需要知道令牌所代表的含義,它只知道這是一串字符串,它只需要做到:持有令牌、向授權服務器請求令牌、向受保護資源出示令牌,授權服務器如何頒發令牌,受保護資源如何驗證令牌它都無需關心。
2、授權范圍(scope)
授權范圍,表示一組訪問受保護資源的權限,一般由受保護資源根據自身提供的API進行定義,它界定了客戶端獲取的權限范圍,授權服務器則允許資源擁有者在客戶端發出請求時許可或否決特定的權限范圍。OAuth中使用字符串表示權限范圍,可以用空格分割的列表將它們合並為一個集合,因此權限范圍的值不能包含空格。
3、刷新令牌(refresh_token)
刷新令牌,與訪問令牌的不同在於,該令牌不會被發送給受保護資源,它只是為了當訪問令牌過期后,客戶端不必重新發起授權請求,而是用該令牌向授權服務器請求換取一個新的用於獲取受保護資源的訪問令牌。
五、OAuth的角色與組件的交互
從OAuth 2.0的授權流程中可以知道,主要的幾個流程有資源擁有者委托客戶端訪問受保護資源、客戶端將資源擁有者重定向到身份認證頁、用戶完成身份認證、授權服務器重定向到客戶端頁面、客戶端請求token、授權服務器頒發token、客戶端請求受保護資源,其中由客戶端、授權服務器和受保護資源參與的部分無需用戶(瀏覽器重定向到身份認證頁)的介入,這部分稱之為“后端信道”,由資源擁有者、授權服務器和客戶端參與的部分需要用戶(瀏覽器重定向、身份認證等)的介入,這部分稱之為“前端信道”,這塊可能比較抽象,下面用幾張圖來描述就知道是怎么回事了~~~
1、后端信道
如上圖中,后端信道的交互中,沒有用戶或瀏覽器的操作,都是服務之間的調用,用戶無感知!
2、前端信道
如上圖所示,前端信道中,用戶訪問客戶端、客戶端將用戶重定向到身份認證頁、用戶進行身份認證、授權服務器返回授權碼后重定向至客戶端請求中的頁面、用戶將授權碼發送給客戶端都是需要用戶的介入!
3、端點
授權服務器中的授權端點和令牌端點,授權和頒發令牌這兩個雖然都屬於授權服務器,但在實際的開發過程中,可以分為兩個微服務。
本文是對OAuth 2.0中基本概念的學習,文中的部分內容來自書本,因為感覺書中表述的還是很恰當,部分是按照自己的理解組織的語言,下一篇我會show出我的實戰。最近了解到一種“費曼學習法”,大概意思就是用自己的語言解釋你所學到的知識,然后把它講給不懂的人聽,如果別人能聽懂,說明你也就學懂了。正在努力運用這種學習法,如果看到本文的你,有什么疑惑,歡迎提出來大家一起討論,這樣也能促進共同學習,共同進步,Respect~