開放授權協議OAuth2.0簡介

jopen 9年前發布 | 37K 次閱讀 OAuth2.0 安全相關

可能你跟我一樣,使用過各種第三方開放授權庫(如在你的 APP 中獲取 QQ 照片或微博評論等)來獲取用戶的一些資源,今天跟大家總結分享一下開放授權(OAuth2.0,1.0太復雜已經被棄用)的概念和原理,在以后使用開放授權SDK時能快速高效完成。

 開放授權協議OAuth2.0簡介

OAuth解決了什么問題?

OAuth 產生主要解決了第三方應用訪問用戶在某網站網絡資源的問題。例如,上圖中,用戶在36氪登陸時,可以用 QQ 來登陸,點擊用 QQ 登陸后,就出現了第三方應用36氪想獲取用戶基本的 QQ 信息已經微博評論,然后快速登陸的過程;再例如某個圖片網站想獲取你 QQ 空間的照片,那么就需要跟 QQ 申請獲取空間圖片的權限,而 QQ 會返回界面,讓用戶來選擇是否授權。

OAuth協議的角色

  • Resource Owner(RO):資源所有者,在上面的例子中是 QQ 用戶。
  • Resource Server(RS):資源服務器,在上面例子中是 QQ 微博評論和空間照片這兩個資源 Server,存儲并處理對這些資源的訪問。
  • Authorization Server(AS):授權服務器,認證資源所有者身份并

根據 OAuth2.0 的 RFC 6749,其流程如下圖所示:

 開放授權協議OAuth2.0簡介

A. 用戶使用某應用后,此應用要求用戶授權訪問一些資源。例如第一幅圖中右下角所示 “36氪將獲取以下權限...”。

B. 用戶同意給此應用授權(Grant)。例如第一幅圖,用戶點擊 QQ 賬號確認。

C. 應用使用 B 步驟用戶的授權,向認證服務器(AS)申請訪問令牌(Access Token)

D. 認證服務器(AS)驗證通過后,向應用返回訪問令牌(Access Token)

E. 應用使用獲取到的訪問令牌,向資源服務器(RS)獲取資源。

F. 資源服務器驗證訪問令牌的有效性,驗證通過,給應用提供相應的資源。

OAuth2.0 提出多種授權類型來支持不同類型的第三方應用,有授權碼(Authorization Code Grant)、隱式授權 (Implicit Grant)、RO憑證授權 (Resource Owner Password Credentials Grant)、Client憑證授權 (Client Credentials Grant), 我們只看最廣泛使用的、功能最完整嚴密的授權碼模式。其他可以參考 RFC 6749

授權碼模式

如下圖所示,授權碼模式如下:

 開放授權協議OAuth2.0簡介

A. 用戶訪問應用,應用將用戶引向認證服務器。如第一幅圖,36氪想獲取QQ用戶一些資源,首先將用戶引向QQ的授權頁面(授權服務器返回)。

應用申請認證的 URL,可包含以下參數:

  • response_type:這個值必須是 "code",用于獲取授權碼(authorization code);必選。
  • client_id:應用的 ID 名稱;必選。
  • redirect_uri:重定向鏈接;可選。
  • scope:應用申請權限的范圍;可選。
  • state:當前應用狀態,應用可指定任意值,AS返回此值,主要用于抵制 CSRF 攻擊;可選。

B. 用戶在授權服務器返回的頁面上選擇是否給予此應用授權(用戶必須顯式同意或拒絕)。如第一幅圖,QQ授權服務器返回一個界面,有36氪想獲取的資源,用戶來決定是否給予這些授權。

C. 如果用戶同意授權,認證服務器將用戶轉向應用已經指定的 重定向鏈接(redirection URI),重定向鏈接包必須含一個授權碼(authorization_code);不同意則通過 重定向鏈接(redirection URI) 返回對應的 ERROR 信息。

認證服務器返回給應用的 URI,需要包含的參數如下:

  • code: AS產生的授權碼,為了安全起見,授權碼的有效期一般為10分鐘,應用拿到后只能使用一次;多余一次 AS 拒絕服務。授權碼與應用 ID 以及重定向 URL 一一對應;必選。
  • state: 若應用的請求中包含這個參數,認證服務器的回應也必須一模一樣包含這個參數,主要為了抵制 CSRF 攻擊;必選。

認證服務器返回 ERROR 信息,主要包含:

  • error: 一個 ASCII 編碼的 error code,其值意義包括 invalid_request、unauthorized_client、access_denied、 unsupported_response_type、invalid_scope、server_error、 temporarily_unavailable;必選。
  • error_description:對錯誤的描述;可選。
  • error_uri:對于錯誤的附加信息,比如出現了這個錯誤,然后指向錯誤的幫助頁面;可選。
  • state:state值如果應用請求的信息里有,必須給予相同值的回復;必選。

D. 應用收到授權碼,加上之前的重定向鏈接和認證應用身份的數據,訪問認證服務器(AS)來獲取授權令牌(Access Token)。

應用向認證服務器申請訪問令牌的HTTP請求,包含以下參數

  • grant_type:值必須是 "authorization_code";必選。
  • code:認證服務器返回的授權碼;必選。
  • redirect_uri:表示重定向 URI,且必須與A步驟中的該參數值保持一致;必選。
  • client_id:表示應用ID;必選項。

E. 認證服務器收到 D 中的數據后,首先驗證應用合法性,其次驗證 redirect_uri 與 C 中的是否一致,驗證通過后,返回授權令牌

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

  • access_token:表示訪問令牌;必選項。

  • token_type:令牌類型,該值大小寫不敏感,可以是 bearer 類型或 mac 類型;必選項。

  • expires_in:過期時間,單位為秒。如果省略該參數,必須其他方式設置過期時間;推薦使用。

  • refresh_token:更新令牌,用來獲取下一次的訪問令牌,可選項。

  • scope:權限范圍,如果與客戶端申請的范圍一致,可省略此項。

舉例說明授權碼模式

這個例子是The OAuth 2.0 Authorization Framework-RFC6749上的。

與授權碼模式的 A B C D E 分別對應。

A

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

B

用戶選擇同意還是拒絕,這里沒有產生動作。

C

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

ERROR 時返回:

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

D

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

E

HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache

{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter":"example_value"
}

還可以參考第三方開放授權的文檔,比如 QQ新浪微博等,都有對他們自己開放授權 SDK 的詳細介紹。

來自:http://stackvoid.com/introduce-to-oath2.0/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!