OAuth 2.0

The OAuth 2.0 Authorization Frameworkhtml

OAuth 2.0受權框架支持第三方支持訪問有限的HTTP服務,經過在資源全部者和HTTP服務之間進行一個批准交互來表明資源者去訪問這些資源,或者經過容許第三方應用程序以本身的名義獲取訪問權限。web

爲了方便理解,能夠想象OAuth2.0就是在用戶資源和第三方應用之間的一箇中間層,它把資源和第三方應用隔開,使得第三方應用沒法直接訪問資源,從而起到保護資源的做用。json

爲了訪問這種受保護的資源,第三方應用(客戶端)在訪問的時候須要提供憑證。即,須要告訴OAuth2.0你是誰你要作什麼。瀏覽器

你能夠將用戶名和密碼告訴第三方應用,讓第三方應用直接以你的名義去訪問,也能夠受權第三方應用去訪問。服務器

能夠聯想一下微信公衆平臺開發,在微信公衆平臺開發過程當中當咱們訪問某個頁面,頁面可能彈出一個提示框應用須要獲取咱們的我的信息問是否容許,點確認其實就是受權第三方應用獲取咱們在微信公衆平臺的我的信息。這裏微信網頁受權就是使用的OAuth2.0。微信

1.  Introduction

在傳統的client-server認證模型中,客戶端經過提供資源全部者的憑證來請求服務器訪問一個受限制的資源(受保護的資源)。爲了讓第三方應用能夠訪問這些受限制的資源,資源全部者共享他的憑證給第三方應用。app

1.1.   Roles

OAuth定義了四種角色:微信公衆平臺

  • resource owner(資源全部者)
  • resource server(資源服務器)
  • client(客戶端):表明資源全部者而且通過全部者受權去訪問受保護的資源的應用程序
  • authorization server(受權服務器):在成功驗證資源全部者並得到受權後向客戶端發出訪問令牌

1.2.  Protocol Flow

抽象的OAuth2.0流程如圖所示:框架

  1. (A)  客戶端向資源全部者請求其受權
  2. (B)  客戶端收到資源全部者的受權許可,這個受權許但是一個表明資源全部者受權的憑據
  3. (C)  客戶端向受權服務器請求訪問令牌,並出示受權許可
  4. (D)  受權服務器對客戶端身份進行認證,並校驗受權許可,若是都是有效的,則發放訪問令牌
  5. (E)  客戶端向資源服務器請求受保護的資源,並出示訪問令牌
  6. (F)  資源服務器校驗訪問令牌,若是令牌有效,則提供服務

1.3.  Authorization Grant

一個受權許但是一個憑據,它表明資源全部者對訪問受保護資源的一個受權,是客戶端用來獲取訪問令牌的。ide

受權類型有四種:authorization code, implicit, resource owner password credentials, and client credentials

1.3.1.  Authorization Code

受權碼是受權服務器用來獲取並做爲客戶端和資源全部者之間的中介。代替直接向資源全部者請求受權,客戶端定向資源全部者到一個受權服務器,受權服務器反過來指導資源全部者將受權碼返回給客戶端。在將受權碼返回給客戶端以前,受權服務器對資源全部者進行身份驗證並得到受權。由於資源全部者只對受權服務器進行身份驗證,因此資源全部者的憑據永遠不會與客戶機共享。

1.3.2.  Implicit

隱式受權是爲了兼顧到在瀏覽器中用諸如JavaScript的腳本語言實現的客戶端而優化的簡化受權代碼流程。在隱式受權流程中,不是發給客戶端一個受權碼,而是直接發給客戶端一個訪問令牌,並且不會對客戶端進行認證。隱式受權提升了一些客戶端(好比基於瀏覽器實現的客戶端)的響應能力和效率,由於它減小了得到訪問令牌所需的往返次數。

1.3.3.  Resource Owner Password Credentials

資源全部者的密碼憑據(好比,用戶名和密碼)能夠直接做爲受權許可來獲取訪問令牌。這個憑據只應該用在高度信任的資源全部者和客戶端之間(好比,客戶端是系統的一部分,或者特許的應用),而且其它受權模式不可用的時候。

1.3.4.  Client Credentials

客戶端憑據一般用做受權許可

1.3.5.  Access Token

訪問令牌是用來訪問受保護的資源的憑據。一個訪問令牌是一個字符串,它表明發給客戶端的受權。令牌表明資源全部者授予的對特定範圍和訪問的時間(PS:令牌是有範圍和有效期的),並由資源服務器和受權服務器強制執行。訪問令牌能夠有不一樣的格式、結構和使用方法。

1.3.6.  Refresh Token

Refresh Token是用於獲取Access Token的憑據。刷新令牌是受權服務器發給客戶端的,用於在當前訪問令牌已經失效或者過時的時候獲取新的訪問令牌。刷新令牌只用於受權服務器,而且歷來不會發給資源全部者。

刷新的流程如圖所示:

  1. (A)  客戶端請求獲取訪問令牌,並向受權服務器提供受權許可
  2. (B)  受權服務器對客戶端身份進行認證,並校驗受權許可,若是校驗經過,則發放訪問令牌和刷新令牌
  3. (C)  客戶端訪問受保護的資源,並向資源服務器提供訪問令牌
  4. (D)  資源服務器校驗訪問令牌,若是校驗經過,則提供服務
  5. (E)  重複(C)和(D)直到訪問令牌過時。若是客戶端直到訪問令牌已通過期,則跳至(G),不然不能繼續訪問受保護的資源
  6. (F)  自從訪問令牌失效之後,資源服務器返回一個無效的令牌錯誤
  7. (G)  客戶端請求獲取一個新的訪問令牌,並提供刷新令牌
  8. (H)  受權服務器對客戶端進行身份認證並校驗刷新令牌,若是校驗經過,則發放新的訪問令牌(而且,可選的發放新的刷新令牌)

2.  Client Registration

在使用該協議以前,客戶端向受權服務器註冊。

2.1.  Client Types

OAuth定義了兩種客戶端類型:

  • confidential:可以維護其憑證的機密性的客戶端
  • public:不能維護其憑證的機密性的客戶端

2.2.  Client Password

擁有客戶端密碼的客戶端可使用HTTP Basic向服務器進行認證,固然前提是受權服務器支持HTTP Basic認證。

例如:Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

兩者選其一的,受權服務器可能支持在請求體中用下列參數包含客戶端憑據:

  • client_id:必須的,在受權服務器中註冊過的客戶端標識符。
  • client_secret:必須的,客戶端祕鑰。若是祕鑰是空字符串的話能夠省略該參數。

用這兩個參數將客戶端憑據包含在請求體中這種方式不推薦,而且應該限制客戶端不能直接用HTTP Basic認證方案。

3.  Protocol Endpoints

受權處理用兩個受權服務器端點:

  • Authorization endpoint:用於客戶端從資源全部者那裏獲取受權
  • Token endpoint:用於客戶端用受權許可交互訪問令牌

還有一個端點

  • Redirection endpoint:用於資源服務器經過資源全部者用戶代理將包含受權憑據的響應返回給客戶端

3.1.  Authorization Endpoint

受權端點用於和資源全部者交互並獲取一個受權許可的。受權服務器必須首先校驗資源全部者的身份。

3.1.1.  Response Type

客戶端用如下參數通知受權服務器本身渴望的受權類型:

  • response_type:必須的。爲了請求一個受權碼這個值必須是"code",爲了請求一個訪問令牌這個值必須是"token"

3.1.2.  Redirection Endpoint

在完成和資源全部者的交互之後,受權服務器直接將資源全部者的user-agent返回給客戶端。受權服務器重定向到這個user-agent

3.2.  Access Token Scope

受權和令牌端點容許客戶端使用「scope」請求參數指定訪問請求的範圍。反過來,受權服務器使用「scope」響應參數通知客戶機它所發放的訪問令牌的範圍。

4.  Obtaining Authorization

 爲了得到一個訪問令牌,客戶端須要先從資源全部者那裏得到受權。受權是以受權許可的形式來表示的。

OAuth定義了四種受權類型:

  • authorization code
  • implicit
  • resource owner password credentials
  • client credentials

4.1.  Authorization Code Grant

受權碼流程如圖所示:

  1. (A)  客戶端經過將資源全部者的用戶代理指向受權端點來啓動這個流程。客戶端包含它的客戶端標識符,請求範圍,本地狀態,和重定向URI,在訪問被容許(或者拒絕)後受權服務器當即將用戶代理返回給重定向URI。
  2. (B)  受權服務器驗證資源全部者(經過用戶代理),並肯定資源全部者是否授予或拒絕客戶端的訪問請求。
  3. (C)  假設資源全部者受權訪問,那麼受權服務器用以前提供的重定向URI(在請求中或在客戶端時提供的)將用戶代理重定向回客戶端。重定向URI包括受權碼和前面客戶端提供的任意本地狀態。
  4. (D)  客戶端用上一步接收到的受權碼從受權服務器的令牌端點那裏請求獲取一個訪問令牌。
  5. (E)  受權服務器對客戶端進行認證,校驗受權碼,並確保這個重定向URI和第三步(C)中那個URI匹配。若是校驗經過,則發放訪問令牌,以及可選的刷新令牌。

4.1.1.  Authorization Request

客戶端經過使用「application/x-www-form- urlencoding」格式向受權端點URI的查詢組件添加如下參數來構造請求URI

  • response_type:必須的。值必須是"code"。
  • client_id:必須的。客戶端標識符。
  • redirect_uri:可選的。
  • 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

4.1.2.  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

4.1.3.1.  Error Response

  • error:取值以下error_description:可選的
    • invalid_request  
    • unauthorized_client
    • access_denied
    • unsupported_response_type
    • invalid_scope
    • server_error
    • temporarily_unavailable
  • error_description
  • error_uri:可選的

4.1.3.  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

4.1.4.  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"
  }

4.2.  Implicit Grant

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

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

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

隱式受權流程如圖所示:

  1. (A)  客戶端引導資源全部者的user-agent到受權端點。客戶端攜帶它的客戶端標識,請求scope,本地state和一個重定向URI。
  2. (B)  受權服務器對資源全部者(經過user-agent)進行身份認證,並創建鏈接是否資源全部者容許或拒絕客戶端的訪問請求。
  3. (C)  假設資源全部者容許訪問,那麼受權服務器經過重定向URI將user-agent返回客戶端。
  4. (D)  user-agent聽從重定向指令
  5. (E)  web-hosted客戶端資源返回一個web頁面(典型的,內嵌腳本的HTML文檔),並從片斷中提取訪問令牌。
  6. (F)  user-agent執行web-hosted客戶端提供的腳本,提取訪問令牌
  7. (G)  user-agent將訪問令牌傳給客戶端

4.2.1.  Authorization Request

  • response_type:必須的。值必須是"token"。
  • client_id:必須的。
  • redirect_uri:可選的。
  • scope:可選的。

4.3.  Resource Owner Password Credentials Grant

資源全部者密碼憑證授予類型適用於資源全部者與客戶端(如設備操做系統或高度特權應用程序)存在信任關係的狀況。受權服務器在啓用這種授予類型時應該特別當心,而且只在其餘受權流程不可行的時候才容許使用。

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

資源全部者密碼憑證流程如圖:

  1. (A)  資源全部者提供他的用戶名和密碼給客戶端
  2. (B)  客戶端攜帶從資源全部者那裏收到的憑證去受權服務器的令牌端點那裏請求獲取訪問令牌
  3. (C)  受權服務器對客戶端進行身份認證,並校驗資源全部者的憑證,若是都校驗經過,則發放訪問令牌

4.3.1.  Access Token Request

客戶端經過在HTTP請求體中添加"application/x-www-form-urlencoded"格式的參數來向令牌端點請求。

  • grant_type :必須的。並且值必須是"password"。
  • username :必須的。資源全部者的用戶名。
  • password :必須的。資源全部者的密碼。
  • scope:可選的。

例如:

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

  grant_type=password&username=johndoe&password=A3ddj3w

4.3.2.  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"
  }

4.4.  Client Credentials Grant

客戶端用它本身的客戶單憑證去請求獲取訪問令牌

客戶端憑證受權流程如圖所示:

  1. (A)  客戶端用受權服務器的認證,並請求獲取訪問令牌
  2. (B)  受權服務器驗證客戶端身份,若是嚴重經過,則發放令牌

4.4.1.  Access Token Request

  • grant_type:必須的。值必須是"client_credentials"。
  • scope:可選的。

例如:

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

  grant_type=client_credentials

4.4.2.  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,
    "example_parameter":"example_value"
  }

5.  Issuing an Access Token

5.1.  Successful Response

受權服務器發放令牌

  • access_token:必須的。
  • token_type:必須的。好比:"bearer","mac"等等
  • expires_in:推薦的。
  • refresh_token:可選的。
  • scope:可選的。

media type是application/json,參數被序列化成JSON對象。

受權服務器必須包含"Cache-Control"HTTP頭,而且值必須是"no-store"。

例如:

  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"
  }

6.  Refreshing an Access Token

請求參數

  • 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

 

參考

https://tools.ietf.org/html/rfc6749

https://oauth.net/2/

https://aaronparecki.com/oauth-2-simplified/

https://www.oauth.com/oauth2-servers/access-tokens/password-grant/

https://www.oauth.com/oauth2-servers/access-tokens/authorization-code-request/

https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/

https://www.oauth.com/oauth2-servers/device-flow/token-request/

https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/

https://www.oauth.com/oauth2-servers/token-introspection-endpoint/

https://developer.okta.com/blog/2018/05/24/what-is-the-oauth2-implicit-grant-type

https://www.oauth.com/

相關文章
相關標籤/搜索