天天看點

Oauth2.0 授權認證                                        Oauth2.0 授權認證 

                                        Oauth2.0 授權認證

目錄

1. OAuth協定是什麼?. 1

2. 應用場景... 1

3. 名詞定義... 2

4. 主要流程... 2

5. 四種授權模式... 3

6. 授權碼授權方式... 4

  6.1什麼是授權碼模式?. 4

  6.2步驟詳情及接口參數... 6

1. OAuth協定是什麼?

   OAuth是一個關于授權(Authorization)的開發網絡标準,主要應用在第三方登入場景.與以往授權方式不同是OAuth是在服務端進行授權,像CAS是用戶端進行授權,且授權不會使第三方觸及到使用者的賬号資訊(例如使用者名和密碼),即第三方無需使用使用者的使用者名和密碼就可以申請獲得該使用者資源的授權,是以OAuth是安全的.

OAuth是Open Authorization的簡寫.

參考:

  1. RFC 6749
  2. 阮一峰老師網絡日志<了解OAuth2.0>

2.應用場景

任何身份認證,本質上是基于對請求方的不信任産生的,是以,身份認證就是解決身份的可信任問題.

舉個栗子:

當你想用注冊新浪微網誌的時候,注冊又嫌麻煩,然後它允許你使用QQ授權登入.

Oauth2.0 授權認證                                        Oauth2.0 授權認證 

如果你用QQ登入,你就必須讓新浪讀取存儲在QQ上的頭像,昵稱等資訊.

問題是隻有得到使用者授權,QQ才會同意新浪讀取這些資訊,那麼新浪應該怎麼擷取使用者授權呢?

傳統的授權方法:

Oauth2.0 授權認證                                        Oauth2.0 授權認證 

3.名詞解釋

   在了解OAuth2.0之前需要了解幾個專有名詞,友善後續的熟悉oauth:

  1. Third-party application: 第三方應用程式,也稱用戶端(client),即上面的用戶端.
  2. Resource Owner: 資源擁有者,本文也稱使用者(user)
  3. User agent: 使用者代理,即浏覽器或App等.
  4. Authorization server:認證伺服器,即服務提供商專門用來處理認證的伺服器.
  5. Resource server: 資源伺服器,即服務商提供存放使用者生成的資源的伺服器,它與認證伺服器, 可以是同一台伺服器,也可以是不同伺服器.

4.主要流程

OAuth2.0運作流程如下,摘自RFC 6749.

Oauth2.0 授權認證                                        Oauth2.0 授權認證 

主要流程一共涉及四個角色: 用戶端,使用者,認證伺服器和資源伺服器; 共六步分别如下:

(A)授權請求。使用者打開用戶端終端(web or APP)以後,用戶端要求使用者給予授權。這個授權請求可以直接送出給資源所有者。(如圖所示),或最好是間接通過授權層作為中介進行授權。

(B)使用者授權。用戶端收到了一個來自使用者的授權憑證。這個憑證,可以通過四種方式來擷取,至于哪四種,下面有介紹。

(C)請求認證伺服器授權。用戶端使用上面使用者授權得到的憑證向認證伺服器請求一個擁有特定通路權限的通路令牌(access token),注意,access token 是和權限綁定的。

(D)發放令牌。認證伺服器向用戶端發放用戶端在上一步請求的令牌。

(E)請求資源。用戶端使用通路令牌向資源伺服器請求使用者的受保護的資源。

(F)傳回資源。資源伺服器驗證通路令牌是否有效,确認有效則傳回請求的資源。如何判斷是否有效呢,當然是調用認證伺服器的準備好的服務了。
           

5. 四種授權模式

用戶端(webor App)必須得到使用者的授權(authorization grant)後,才能獲得令牌(access token),OAuth2.0有四種授權模式:

• 授權碼模式(Authorization code)

• 簡化模式(implicit)

• 密碼模式(resource owner password credentials)

• 用戶端模式(client credentials)

6.授權碼模式詳解

6.1什麼是授權碼模式?

授權碼模式特點是通過用戶端背景伺服器,與”服務提供商”的認證伺服器進行互動,授權碼方式用于同時擷取access token和refresh token,并對信任的用戶端進行了優化.由于這是一個重定向的流程,client必須能與resource owner的user-agent(通常是浏覽器)進行互動且能夠接收到authorization server通過重定向傳入的請求.

下面是引用RFC 6749官網:

Oauth2.0 授權認證                                        Oauth2.0 授權認證 

對上面流程的解析:

(A)用戶端将使用者浏覽器引導向認證端。用戶端包含了用戶端辨別 client_id,請求授權範圍 scope,本地狀态state,回調位址 redirect_uri,一旦被授權(或被拒絕),認證伺服器将會把回調位址傳回給浏覽器。

(B)使用者操作授權,比如使用者進行選擇資源範圍,輸入密碼點确定發送請求,決定是否給用戶端授權。

(C)認證伺服器校驗使用者真實性,假設使用者給予授權,認證伺服器将使用者導向用戶端事先指定的回調位址 redirect_uri,回調位址後面同時附上一個授權碼code 和之前設定的 state (這裡的state,其實就是用戶端預留的,用于當授權成功後,執行某些事件等,比如可以放一個js的方法名)。

(D)用戶端使用上一步傳回的授權碼 code 附上之前用來擷取授權碼的回調位址 redirect_uri 向認證伺服器請求一個通路令牌 (access token)。這一步是在用戶端的背景的伺服器上完成的,對使用者不可見。

(E)認證伺服器核對了授權碼和重定向URI,和在(C)步驟中的兩個參數比對确認無誤後,向用戶端發送通路令牌(access token)和可選的重新整理令牌(refresh token)。
           

下面來一個原型圖和時序圖友善更好的了解:

Oauth2.0 授權認證                                        Oauth2.0 授權認證 
Oauth2.0 授權認證                                        Oauth2.0 授權認證 

6.2步驟詳情及接口參數

步驟1: 用戶端申請認證的URI

包含以下參數:

response_type: 必須,授權類型. (如授權碼模式為authorization code)

client_id:必須,用戶端ID.(如QQ登入授權,此ID為APPID)

redirect_uri: 可選,重定向urI.

scope: 可選,表示申請權限的範圍.

state: 表示用戶端的目前狀态,可以指定任意值,認證伺服器會原封不動傳回這個值.

示例:

http://10.231.111.208:8080/leadToLogin?response_type=code&client_id=client&state=xiaomi&redirect_uri=http://10.231.111.208:8081/index
           

對比其他應用通過QQ登入,請求code:

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101019034&response_type=code&scope=get_info%2Cget_user_info&redirect_uri=https%3A%2F%2Fpassport.weibo.com%2Fothersitebind%2Fbind%3Fsite%3Dqq%26state%3DCODE-tc-1HVZ4j-22WtNd-qnXUO5Rhlup4BM1a10cca%26bentry%3Dminiblog%26wl%3D&display=
           

步驟2:認證伺服器回應用戶端的URI

包含以下參數:

code: 必須,授權碼.該授權碼可以設定失效時間,用戶端隻能使用該碼一次,否則會被授權伺服器拒絕.該碼與用戶端ID和重定向的URI是一一對應關系.

state: 如果用戶端的請求中包含這個參數,認證伺服器的回應也必須一模一樣包含這個參數.

示例:

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

步驟3:用戶端向認證伺服器申請令牌的http請求

包含以下參數:

grant_type: 必選項,辨別使用授權模式.此處為"authorization code".

code: 必選項,表示上一步擷取的授權碼.

redirect_uri: 必選項,表示重定向URI,且必須與步驟1參數保持一緻.

client_id: 必選項, 表示用戶端ID.

示例:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
           

對比其他應用通過微信登入,通過code擷取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
           

步驟4,認證伺服器發送HTTP回複

包含以下參數:

access_token:  必選項,表示通路令牌.

refresh_token: 可選項,表示更新令牌,用來擷取下一次的通路令牌.

token_type: 必選項,表示令牌類型,不分大小寫,可以是bearer類型或mac類型.

expires_in: 表示過期時間,機關為秒. 如果省去該參數,必須在其他地方設定過期時間.

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",
       "expires_in":6666,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }
           

對比其他應用通過微信登入,傳回樣例:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
           

接口5: 更新令牌

       如果用戶端的通路令牌access_token已經過期,則需要使用更新令牌refresh_token,申請一個新的通路令牌.

用戶端發出更新令牌的http請求,包含以下參數:

grant_type:  必選項,表示使用授權模式, 此處固定值:”refresh_token”.

Refresh_token: 必選項,表示之前收到的更新令牌.

Scope: 表示申請授權範圍,不可以超出上一次申請的範圍,如果省去該範圍,則表示和上次一緻.

示例:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
           

繼續閱讀