對OAuth2.0協議的理解和測試demo


1. 什么是OAuth

OAuth(開放授權)是一個開放標准,允許用戶授權第三方網站訪問他們存儲在另外的服務提供者上的信息,而不需要將用戶名和密碼提供給第三方網站或分享他們數據的所有內容。
OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的網站(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth讓用戶可以授權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非所有內容。

2. OAuth中的術語介紹

角色

OAuth定義了四個角色:

  • 資源所有者(用戶)
  • 資源服務器
  • 認證服務器(可以是與資源服務器相同的服務器)
  • 客戶端(第三方應用)

用戶

OAuth 2.0規范將用戶稱為“資源所有者”。資源所有者是授予其帳戶某些部分訪問權限的人。在這種情況下,資源可以是數據(照片,文檔,聯系人),服務(發布博客條目,轉移資金)或任何其他需要訪問限制的資源。任何想要代表用戶行事的系統必須首先獲得他們的許可。

資源服務器

資源服務器是包含第三方應用程序正在訪問的用戶信息的服務器。資源服務器必須能夠接受並驗證訪問令牌,並在用戶允許時授予請求。資源服務器不一定需要知道應用程序。

認證服務器

認證服務器,處理用戶的授權請求,以及給客戶端(第三方用戶)授予一個訪問令牌(access_token)。因此,認證服務器通常具有兩個主URL,一個用於授權請求,一個用於給客戶端授予訪問令牌。這些通常是這樣的:

客戶端

客戶端是試圖代表用戶行動或訪問用戶資源的應用程序。在客戶端可以訪問用戶的帳戶之前,需要獲得權限。

授權碼

授權碼是用於和認證服務器交換令牌使用的,在用戶同意授權請求后,認證服務器會返回一個授權碼給客戶端,然后客戶端使用授權碼和認證服務器交換訪問令牌。

訪問令牌(access_token)

訪問令牌是向資源服務器發出經過身份驗證的請求時使用的字符串。字符串本身對使用它的應用程序沒有意義,但表示用戶已授權第三方應用程序訪問其帳戶。令牌具有相應的訪問持續時間,范圍以及服務器所需的其他可能信息。客戶端通過使用訪問令牌向資源服務器獲取指定的信息。

刷新令牌

刷新令牌是一個字符串,用於在訪問令牌過期時獲取新的訪問令牌。並非所有資源服務器都使用刷新令牌。

3. 協議運作流程

下面是OAuth2.0協議的運作流程圖,圖片來源:OAuth2.0協議草案V21的1.2節

上圖描述了四個角色之間的互動,主要包括下面幾個步驟:

(A) 客戶端向用戶(資源擁有者)發出授權請求;
(B) 用戶同意授權請求;
(C) 客戶端向認證服務器進行身份認證,並請求獲取訪問令牌;
(D) 認證服務器對客戶端進行身份校驗,如果有效,則發放令牌;
(E) 客戶使用令牌向資源服務器獲取受保護的資源;
(F) 資源服務器驗證令牌,如果有效,則同意客戶端的資源訪問請求

在步驟(B)中,用戶要如何接受客戶端的授權請求呢?OAuth2.0協議規定了四種授權類型:authorization code(授權碼模式), implicit(簡化模式), resource owner password credentials(密碼模式), and client credentials(客戶端模式)。它還提供了一種用於定義其他授權類型的擴展機制。這里我介紹下授權碼模式。

4 authorization code(授權碼模式)

下面是授權碼模式的流程圖,圖片來源:OAuth2.0協議草案V21的4.1節

步驟說明:

(A) 客戶端向認證服務器發出授權請求,並將用戶導向認證服務器,其中 Client Identifier 表示客戶端身份標識,Redirection URI 表示重定向uri;
(B) 認證服務器對資源所有者進行身份驗證,並確定資源所有者是否授予或拒絕客戶端的訪問請求;
(C) 假如用戶同意授權,那么認證服務器會重定向到(A)中指定的uri,並返回一個code(授權碼);
(D) 客戶端使用(C)中獲取的授權碼code向認證服務器交換令牌(token);
(E) 認證服務器對客戶端的身份進行校驗,比如說判斷code是否有效,uri是否匹配等,如果通過則同意發放令牌。

在上面(A)中的 Client IdentifierRedirection URI 是如何獲得的呢?這里我們以github為例,簡單說明一下

假如說我們要登陸開源中國,在登錄界面我們可以看到,它支持通過微信、QQ、github等賬號登陸。如果我們選擇github賬號登陸,那么開源中國就是客戶端,github就是認證服務器,同時也是資源服務器。開源中國在使用OAuth2.0協議和github通信前,首先要到github上面注冊OAuth Apps,注冊需要的信息包括Application name、Homepage URL、Application description和Authorization callback URL,注冊成功后,github會提供client_id和client_secret,其中client_id就表示 Client IdentifierRedirection URI 就是注冊時填寫的Authorization callback URL。

下面是上面這些步驟所需要的參數。
(A)中,客戶端申請認證的URI,包含以下參數:

  • response_type:表示授權類型,必選項,此處的值固定為"code"
  • client_id:表示客戶端的ID,必選項
  • redirect_uri:表示重定向URI,可選項
  • scope:表示申請的權限范圍,可選項
  • state:客戶端用於維護請求和回調之間狀態的不透明值。推薦使用

客戶端可構造一個包含上述參數的uri,將用戶導向認證服務器,例如:

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com

(C)中,服務器回應客戶端的URI,包含以下參數:

code:表示授權碼,必選項。該碼的有效期應該很短,通常設為10分鍾,客戶端只能使用該碼一次,否則會被授權服務器拒絕。該碼與客戶端ID和重定向URI,是一
一對應關系。
state:如果客戶端的請求中包含這個參數,認證服務器的回應也必須一模一樣包含這個參數。

一個成功的例子:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

一個失敗的例子:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?error=access_denied&state=xyz

(D)中,客戶端向認證服務器申請令牌的HTTP請求,包含以下參數:

grant_type:表示使用的授權模式,必選項,此處的值固定為"authorization_code"。
code:表示上一步獲得的授權碼,必選項。
redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該參數值保持一致。
client_id:表示客戶端ID,必選項。

例如:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

(E)中,認證服務器發送的HTTP回復,包含以下參數:

access_token:表示訪問令牌,必選項。
token_type:表示令牌類型,該值大小寫不敏感,必選項,可以是bearer類型或mac類型。
expires_in:表示過期時間,單位為秒。如果省略該參數,必須其他方式設置過期時間。
refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項。
scope:表示權限范圍,如果與客戶端申請的范圍一致,此項可省略。

一個成功的例子如下:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"bearer",
}

5. 模擬OAuth工作流程的demo

demo寫的很簡單,僅僅是為了幫助協議工作流程~
基於OAuth2.0協議,模擬客戶端實現,代碼下載地址
基於OAuth2.0協議,模擬服務端實現,代碼下載地址
基於OAuth2.0協議,實現訪問github的客戶端,代碼下載地址

參考網站:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM