OAuth 2.0


OAuth 2.0 簡介

概述

OAuth 2.0 協議為用戶資源的授權提供了一個安全、開放而又簡易的標准,支持第三方服務訪問有限的 HTTP 服務,通過在資源所有者和 HTTP 服務之間進行一個批准交互來代表資源者去訪問這些資源,或者通過允許第三方應用程序以自己的名義獲取訪問權限。

通俗來說,OAuth 2.0 是一個第三方認證技術方案,最主要是解決認證協議的通用標准問題,因為要實現跨系統認證,各系統之間要遵循一定的接口協議。

為了方便理解,可以想象 OAuth2.0 就是在用戶資源和第三方應用之間的一個中間層,它把資源和第三方應用隔開,使得第三方應用無法直接訪問資源,從而起到保護資源的作用。為了訪問這種受保護的資源,第三方應用(客戶端)在訪問的時候需要提供憑證,也就是需要告訴 OAuth2.0 你是誰你要做什么。你可以將用戶名和密碼告訴第三方應用,讓第三方應用直接以你的名義去訪問,也可以授權第三方應用去訪問。

抽象的解釋往往不得精髓,那么接下來我們通過在客戶端使用微信登錄,來進一步說明此協議相關概念。用戶進入客戶端(網站、小程序、APP等),通過客戶端提供的微信登錄方式,以微信賬號登錄此系統(用戶是微信中個人信息資源的擁有者)

image

用戶(資源擁有者)點擊微信登錄,頁面響應微信登錄二維碼,用戶通過掃描授權授權登錄二維碼,開始給客戶端授權,掃描二維碼之后,用戶微信中會彈出授權操作,用戶同意給客戶端授權,微信會對資源擁有者的身份進行驗證,驗證通過后,微信會詢問用戶是否給授權網站訪問自己的微信數據,用戶點擊"確認登錄"表示同意授權,微信認證服務器會頒發一個授權碼,並重定向到網站。

image

用戶授權完成后,客戶端獲取到授權碼,請求認證服務器申請令牌,此過程用戶看不到,客戶端應用程序請求認證服務器,請求攜帶授權碼。認證服務器接受到客戶端請求后,認證服務器驗證客戶端請求的授權碼,如果合法則給客戶端頒發令牌(客戶端訪問資源的通行證),此交互過程用戶看不到,當客戶端拿到令牌后,用戶在網站看到已經登錄成功。用戶登錄成功后,客戶端通過攜帶令牌請求資源服務器的用戶資源,資源服務器驗證令牌是否合法,如果合法則返回用戶的基本信息。
授權第三方應用獲取用戶在微信服務的個人信息,其實就是 OAuth2.0 的作用。

image


角色

客戶端:代表資源所有者並且經過所有者授權去訪問受保護的資源的應用程序,本身不存儲資源.需要通過資源擁有者的授權去請求資源服務器的資源,比如:Android客戶端、Web客戶、微信客戶端等。

資源所有者:通常為用戶,也可以是應用程序,即該資源的擁有者。

資源服務器:存儲資源的服務器,比如,網站用戶管理服務器存儲了網站用戶信息,網站相冊服務器存儲了用戶的相冊信息,微信的資源服務存儲了微信的用戶信息等。客戶端最終訪問資源服務器獲取資源信息。

授權服務器:用來對資源擁有的身份進行認證、對訪問資源進行授權。客戶端要想訪問資源需要通過認證服務器由資源擁有者授權后方可訪問。


常用術語

客戶憑證(client Credentials):客戶端的 ctientld 和密碼用於認證客戶。

令牌(tokens):授權服務器在接收到客戶請求后,頒發的訪問令牌,也是 OAuth 2.0 中最重要的東西。

作用域(scopes):客戶請求訪問令牌時,由資源擁有者額外指定的細分權限 (permission)


令牌類型

授秘碼:僅用於授權碼授權類型,用於交換獲取訪問令牌和刷新令牌。

訪問令牌:用於代表一個用戶或服務直接去訪問受保護的資源。

刷新令牌:用於去授權服務器獲取一個刷新訪問令牌。

BearerToken:不管誰拿到 Token 都可以訪問資源.類似現金。

Proof of Possession(PoP)Token:可以校驗 client 是否對 Token 有明確的擁有權。

特點

優點

  • 更安全,客戶端不接觸用戶密碼,服務器端更易集中保護廣泛傳播並被持續采用
  • 短壽命和封裝的token
  • 資源服務器和授權服務器解耦集中式授權,簡化客戶端
  • HTTP/JSON友好,易於請求和傳遞token考慮多種客戶端架構場景
  • 客戶可以具有不同的信任級別缺點

缺點

  • 協議框架太境乏,造成各種實現的兼容性和互操作性差不是一個認證協議,本身並不能告訴你任何用戶信息。

授權流程

抽象的 OAuth2.0 授權認證流程如圖所示:
image

  • (A):請求授權,客戶端向資源所有者請求其授權。
  • (B):授權許可,客戶端收到資源所有者的請求並授權許可,這個授權許可是一個代表資源所有者授權的憑據。
  • (C):請求令牌,客戶端向授權服務器請求訪問令牌,並出示授權許可。
  • (D):令牌許可,授權服務器對客戶端身份進行認證,並校驗授權許可,如果都是有效的,則發放訪問令牌。
  • (E):請求資源,客戶端向資源服務器請求受保護的資源,並出示訪問令牌。
  • (F):響應資源,資源服務器校驗訪問令牌,如果令牌有效,則提供服務。

OAuth 2.0 授權模式

授權碼模式(Authorization Code Grant)

授權碼模式是最復雜,同時也是使用最廣泛的授權模式,授權碼流程如圖所示:

image

  • (A):客戶端通過將資源所有者的用戶代理指向授權端點來啟動這個流程。客戶端包含它的客戶端標識符,請求范圍,本地狀態,和重定向URI,在訪問被允許(或者拒絕)后授權服務器立即將用戶代理返回給重定向URI。
  • (B):授權服務器驗證資源所有者(通過用戶代理),並確定資源所有者是否授予或拒絕客戶端的訪問請求。
  • (C):假設資源所有者授權訪問,那么授權服務器用之前提供的重定向URI(在請求中或在客戶端時提供的)將用戶代理重定向回客戶端。重定向URI包括授權碼和前面客戶端提供的任意本地狀態。
  • (D):客戶端用上一步接收到的授權碼從授權服務器的令牌端點那里請求獲取一個訪問令牌。
  • (E):授權服務器對客戶端進行認證,校驗授權碼,並確保這個重定向URI和第三步(C)中那個URI匹配。如果校驗通過,則發放訪問令牌,以及可選的刷新令牌。

Authorization Request

客戶端通過使用“application/x-www-form- urlencoding”格式向授權端點URI的查詢組件添加以下參數來構造請求URI。

  • response_type:響應類型必須是 code,必須攜帶。
  • client_id:客戶端標識,必須攜帶。
  • redirect_uri:重定向 RUI,可選。
  • scope:請求訪問的范圍,可選。
  • state:一個不透明的值用於維護請求和回調之間的狀態,授權服務器在將用戶代理重定向會客戶端的時候會帶上該參數,可選的
    例如:

  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

Authorization Response

如果資源所有者授權訪問請求,授權服務器發出授權代碼並通過使用“application/x-www-form- urlencoding”格式向重定向URI的查詢組件添加以下參數,將其給客戶端。

  • code:必須的。授權服務器生成的授權碼。授權代碼必須在發布后不久過期,以減少泄漏的風險。建議最大授權代碼生命期為10分鍾。客戶端不得多次使用授權代碼。如果授權代碼不止一次使用,授權服務器必須拒絕請求,並在可能的情況下撤銷先前基於該授權代碼發布的所有令牌。授權代碼是綁定到客戶端標識符和重定向URI上的。
  • state:如果之前客戶端授權請求中帶的有"state"參數,則響應的時候也會帶上該參數。
    例如:

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

Access Token Request

客戶端通過使用“application/ www-form-urlencoding”格式發送以下參數向令牌端點發出請求

  • grant_type:必須的。值必須是"authorization_code"。
  • code:必須的。值是從授權服務器那里接收的授權碼。
  • redirect_uri:如果在授權請求的時候包含"redirect_uri"參數,那么這里也需要包含"redirect_uri"參數。而且,這兩處的"redirect_uri"必須完全相同。
  • client_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

Access Token Response

例如:
  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"
  }


簡化授權碼模式(Implicit Grant)

隱式授權用於獲取訪問令牌(它不支持刷新令牌),它針對已知的操作特定重定向URI的公共客戶端進行了優化。這些客戶端通常在瀏覽器中使用腳本語言(如JavaScript)實現。

因為它是基於重定向的流程,所以客戶端必須有能力和資源所有者的用戶代理(典型地,是一個Web瀏覽器)進行交互,同時必須有能力接收來自授權服務器的重定向請求。

隱士授權類型不包含客戶端身份驗證,它依賴於資源所有者的存在和重定向URI的注冊。由於訪問令牌被編碼到重定向URI中,所以它可能暴露給資源所有者以及同一台設備上的其它應用。

隱式授權流程如圖所示:

image

  • (A):客戶端引導資源所有者的user-agent到授權端點。客戶端攜帶它的客戶端標識,請求scope,本地state和一個重定向URI。
  • (B):授權服務器對資源所有者(通過user-agent)進行身份認證,並建立連接是否資源所有者允許或拒絕客戶端的訪問請求。
  • (C):假設資源所有者允許訪問,那么授權服務器通過重定向URI將user-agent返回客戶端。
  • (D):user-agent遵從重定向指令
  • (E):web-hosted客戶端資源返回一個web頁面(典型的,內嵌腳本的HTML文檔),並從片段中提取訪問令牌。
  • (F):user-agent執行web-hosted客戶端提供的腳本,提取訪問令牌
  • (G):user-agent將訪問令牌傳給客戶端

密碼模式(Resource Owner Password Credentials Grant)

資源所有者密碼憑證授予類型適用於資源所有者與客戶端(如設備操作系統或高度特權應用程序)存在信任關系的情況。授權服務器在啟用這種授予類型時應該特別小心,並且只在其他授權流程不可行的時候才允許使用。

這種授權類型適合於有能力維護資源所有者憑證(用戶名和密碼,典型地,用一個交互式的表單)的客戶端。

資源所有者密碼憑證流程如圖:

image

  • (A):資源所有者提供他的用戶名和密碼給客戶端。
  • (B):客戶端攜帶從資源所有者那里收到的憑證去授權服務器的令牌端點那里請求獲取訪問令牌。
  • (C):授權服務器對客戶端進行身份認證,並校驗資源所有者的憑證,如果都校驗通過,則發放訪問令牌。

客戶端模式(Client Credentials Grant)

客戶端用它自己的客戶單憑證去請求獲取訪問令牌,客戶端憑證授權流程如圖所示:

image

  • (A):客戶端用授權服務器的認證,並請求獲取訪問令牌。
  • (B):授權服務器驗證客戶端身份,如果嚴重通過,則發放令牌。

更新令牌

如果用戶訪問的時候,客戶端的"訪問令牌"已經過期,就是圖中 E -> F 的過程,此時則需要使用"更新令牌"申請一個新的訪問令牌,不需要再經過 A -> E 的過程,直接通過 G -> H 的步驟申請新令牌。

image

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

  • granttype:表示使用的授權模式,此處的值固定為"refreshtoken",必選項。
  • refresh_token:表示早前收到的更新令牌,必選項。
  • scope:表示申請的授權范圍,不可以超出上一次申請的范圍,如果省略該參數,則表示與上一次一致。


免責聲明!

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



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