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

1. 什麼是OAuth

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

2. OAuth中的術語介紹

角色

OAuth定義了四個角色:git

  • 資源全部者(用戶)
  • 資源服務器
  • 認證服務器(能夠是與資源服務器相同的服務器)
  • 客戶端(第三方應用)

用戶

OAuth 2.0規範將用戶稱爲「資源全部者」。資源全部者是授予其賬戶某些部分訪問權限的人。在這種狀況下,資源能夠是數據(照片,文檔,聯繫人),服務(發佈博客條目,轉移資金)或任何其餘須要訪問限制的資源。任何想要表明用戶行事的系統必須首先得到他們的許可。github

資源服務器

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

認證服務器

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

客戶端

客戶端是試圖表明用戶行動或訪問用戶資源的應用程序。在客戶端能夠訪問用戶的賬戶以前,須要得到權限。微信

受權碼

受權碼是用於和認證服務器交換令牌使用的,在用戶贊成受權請求後,認證服務器會返回一個受權碼給客戶端,而後客戶端使用受權碼和認證服務器交換訪問令牌。app

訪問令牌(access_token)

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

刷新令牌

刷新令牌是一個字符串,用於在訪問令牌過時時獲取新的訪問令牌。並不是全部資源服務器都使用刷新令牌。網站

3. 協議運做流程

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

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

(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的客戶端,代碼下載地址

參考網站:

相關文章
相關標籤/搜索