OAuth 2.0協議(rfc 6749)解讀與用法說明


一. RFC解讀

  • 官方rfc:   https://tools.ietf.org/html/rfc6749

前言:

authorization:授權(v.), 重點在"賦予"這個動作, 行為主體是服務器,重點也在服務器方,即服務器給予某人xxx
authenticate: 認證(v.), 重點在"證明"這個動作, 行為主體也是服務器, 但重點是客戶方,即客戶方被驗證.
grant: 授予的權利(n.), 重點在被賦予的那個東東本身, 行為主體是服務器+客戶端, 這個"權利"從服務器方來,被賦予給了客戶方. 至於我們常說的授權, 完整的就是表達就是authorization grant.

注: 所謂客戶端,服務端是相對而言...

目錄&摘要:

1.協議的整體介紹

   1.1 協議中划分了4種角色:
  resource owner, resource server, client, authorization server

  1.2 協議制定的基本流程(Flow)
  1.3 協議核心步驟:權限授予, 包含4種授權方式:
  Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials

2.協議的前提:客戶端注冊

   2.1 客戶端類型:
  從安全的角度划分: confidential, public
  從app實現方式划分: web application, user-agent-based application, native application
   2.2 客戶端身份信息
   2.3 客戶端認證

3.協議中的端點(從訪問的api維度來說明)

4.詳解授權碼類型的整個流程

 

1.協議介紹

1.1.角色定義(Roles)

OAuth定義了四種角色

  • resource owner

   資源所有者.一個可以去授予訪問受保護資源(protected resource)的實體, 當着個owner是一個自然人時,它被稱作是一個終端用戶(end-user)
    比如, github上某個的代碼的所有者,即me!。

  • resource server

     資源服務器.托管受保護資源的服務器,能夠接收並響應使用訪問令牌(access tokens)訪問受保護資源(protected resource)的請求
     比如, github, 當有請求攜帶token想要clone代碼時, github可以處理這個請求

  • client

     客戶端.一個可以代表resource owner並能構造訪問受保護資源(protected resource)請求的應用.
     "client"這個術語並沒有確定的特征,即這個應用是否運行在服務器上, 還是桌面或者其他設備上都可能。
     比如, 某個想要拉取我github上代碼的一個應用

  • authorization server

   授權服務器.一個用來給client簽發訪問令牌(access tokens)的服務器,當然是指在對resource owner認證成功進而取得了授權之后。
      例如, github的授權服務器(https://github.com/settings/applications/new), 訪問這個服務器后會讓我輸入賬號(認證), 以及詢問我是否允許某個client具備clone權限。

 

注: 至於resource server和authorization server之間的交互不是本協議所定義的,二者可以是同一個當然也可以是不同的服務器,例如,github, 至少在我們看來二者是一個地址提供的...

 

1.2 協議的基本流程(Protocol Flow)

 +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

                     Figure 1: Abstract Protocol Flow

  

  (A) client請求Resource Owner給它授權, 可以如上圖所示向Resource Owner直接請求授權,
      但更推薦的是間接通過authorization server獲得授權(后面會詳細說)

  (B) client得到授權(authorization grant),即拿到了一個能代表resource owner權利的憑證, 本文定義了四種授權類型,
        也可以是擴展授權類型。具體哪種類型取決於client想要的以及授權服務器所能提供的。

  (C) client拿着授權(grant)去authorization server請求訪問令牌.

  (D) 授權服務器對client進行身份驗證(authenticates)並校驗其權限(validates the authorization grant),
              如果有效,則頒發access token。

  (E) client攜帶access token去resource server那里請求protected resource, 后者服務器會通過access token進行身份驗證。

  (F) resource server對access token校驗后如果判定是有效的,則滿足client的請求。

 

【小小結】:
client在得到owner的授權后,拿着授權憑證去authorization server那里換取token, 最后拿着token去resourceserver訪問資源。

 


1.3. 權限授予(Authorization Grant)

wxy: client說自己得到了owner的授權,但口說無憑,所以需要一個機制讓授權成立, 所以本文定義了4種方式.


1.授權碼(Authorization Code)

 相對於直接從owner那邊獲取授權, 這種方式是向授權服務器(authorization server)請求一種叫做授權碼(authorization code)的授權憑據.
 客戶端會首先會將owner引導到授權服務器(通過user-agent,定義在 [RFC2616]), 然后再攜帶着授權碼(authorization code)將owner引導回客戶端.

 在引導owner回到client之前, authorization server會對owner進行認證(authenticates), 然后取得授權資格.
 由於owner只能被authorization server認證, 所以owner的credentials永遠不會讓client獲知。

 授權碼(authorization code)方式具備一些重要的安全方面優勢(security benefits),
 比如認證client的能力,除了會不透過owner的user-agent而是直接將access token傳輸給client外, 還有可能將其暴露給其他人, 包括owner.

wxy: 傳統的直接從owner那邊獲得授權不是很安全,因為相當於owner將自己的賬號密碼直接給了client,
但是有了authorization server后,由他來負責和owner和client分別單線打交道:
首先, authorization server和owner對話, 判斷owner是否同意授權
然后, authorization server和client打交道, 同意授權則頒發一個授權碼給client
這個授權碼是authorization server頒發的,所以client自然可以拿着這個碼去authorization server那邊得到認證


2.隱式授權(Implicit)
 是簡化版的授權碼方式. 此時的client由瀏覽器中的腳本語言比如js來實現。不同於前者給client頒發的是授權碼,
 在這種授權交互里是直接給client頒發access token(作為owner的授權結果).
 所以說這種授權是隱式的,因為中間憑據(比如授權碼)的生成以及使用這種憑據獲取access token的過程都沒有。

 在這種隱式授權方式下, authorization server不需要對client進行認證就會頒發access token. 在某些情況下,
 可以通過驗證用於發送access token的重定向URI來實現對client的身份認證(verified via the redirection URI
 used to deliver the access token to the client).另外, access token可能會暴露給owner或其他具有訪問owner's user-agent權限的應用。

 隱式授權方式提高了某些client(比如那些in-browser方式實現的應用)的響應能力和效率, 因為他減少了獲取access token所需的交互次數.
    然而, 這種便利性的代價就是增加了安全的風險, 見10.3和10.6章節...

wxy: 客戶端去授權服務器那邊獲取的直接就是access token, 這個過程可以用如下的流程來描述:
client將owner引導到授權服務器側, owner輸入賬號密碼后,client直接得到access token.
關於, 對client的認證, 一般是不需要的,但有的時候可以校驗redirect URI, 因為這個URI一般就是client的地址。

 

3.資源owner的密碼憑據(Resource Owner Password Credentials)
 資源owner的password憑據(比如賬號和密碼), 可以直接作為認證授權來獲得access token.
 該憑證僅用在owner和client之間有較高信任度的情況下(例如,client是設備操作系統的一部分,或者是高特權客戶端應用),
 或者其他授權類型不是可用(例如授權碼)的情況下。


4.client的憑據(Client Credentials)
 當protected resources是受client控制, 或者事先已安排受authorization server所保護時, 客戶端憑據(或其他形式的客戶端身份驗證)可以用來作為授權.
 通常,當client在行使自己的權利(此時也可將其看做是resource owner)或者基於一個之前與授權服務器應景建立好的授權關系,
 一個client credential會被用做一個授予的權限(an authorization grant)。


【小小結】:
Authorization Code:
  client領着owner去authorization server獲取code, 然后client拿着code獲取access token.
Implicit:
  client領着owner去authorization server直接獲取access token.
Resource Owner Password Credentials:
  client拿着owner的憑據去獲取access token
Client Credentials:
  client拿着自己的憑據去獲取access token

 


2.客戶注冊(Client Registration)

在啟動協議交互之前, client需要先去authorization server那里進行注冊.

所謂的客戶注冊並不需要授權服務器(authorization server)與客戶端(client)之間進行直接交互。
When supported by the授權服務器,注冊可以依靠其他方式建立信任並獲得所需的客戶端屬性(比如重定向URI,客戶端類型).
例如, 注冊可以通過使用自簽發(self-issued)或第三方簽發(third-party-issued)的斷言(assertion)來完成,
或由授權服務器通過使用一個受信任的channel來扮演一個客戶端發現的角色。

在進行客戶端注冊時,客戶端開發人員應提供如下的信息:

  o  客戶端類型(client type), 詳見2.1
       wxy:即表明自己是"注重隱式保護的人"還是"隨隨便便"的人

  o  客戶端的重定向URI,詳見3.1.2

  o  包括授權服務器所需的任何其他信息(例如,應用程序名稱,網站,說明,徽標圖片,接受法律條款)

 

2.1 客戶端類型(Client Type)

OAuth根據它們與授權服務器進行安全地身份認證的能力(即維護其客戶憑證的機密性), 定義了兩種客戶端類型:

  • confidential, 機密型

   這種類型的client有能力維護自己的credential的機密性(比如一個實現於安全服務器上的客戶端, 其會限制對自己credential的訪問),
     或者使用其他途徑反正要能夠安全地進行身份認證的客戶端

    wxy: 這里暫且存留一個疑問,這個credential是什么意思,是指client自己的憑據還是指授權服務器辦法的授權code?
      抑或是一個廣義的詞匯, 代表了所有"憑據"類信息, 包括code, access token等...

  • public, 公共型

    ...

為客戶端划分類型是基於授權服務器對安全認證的定義和其所能接受的暴露client credential的級別,而授權服務器自身是不應該去假設客戶端的類型

wxy: 意思是說客戶端自己的類型的定義有client自己定義, 授權服務器只需要知道如果客戶端聲稱自己的是機密的,那么授權服務器要謹慎對待。

本文檔會圍繞如下的客戶端的配置戶或者說是從應用的角度划分的客戶端類型:

  • 客戶端應用(web application)

   是指運行在web服務器上的confidential client。html用戶接口呈現在資源owner所使用設備的user-agent上, 進而owner 通過這個接口得以訪問客戶端。
   而客戶端的credential連同簽發給他的access token都會被存放在web服務器上,並不會暴露給owner,owner也沒辦法主動獲取。

   wxy:這個是我們最典型的使用場景:
    我們自己開發web應用, 比如一個ui/dashboard等運行在web服務器上
    首先, 訪問web應用的url/api會獲取一個html頁面顯示在瀏覽器中,
    然后, 得到的客戶端credential包括access token都會被存放在client自己的應用中

  • 基於user-agent的應用(user-agent-based application)

   這是一種公共的客戶端, 其運行代碼是從web服務器上下載下來然后運行在user-agent(比如瀏覽器)上.
   協議數據和credential對owner來說可以很容易獲得(通常也是直接可見的). 而由於這樣的應用駐留在user-agent中,
   所以他們可以在請求授權時無縫使用的user-agent的功能。

   wxy:這應該是另一個非常典型的使用場景,
    和web應用類似,只不是和授權服務器的交互過程直接在瀏覽器上完成,通常是web服務器提供給瀏覽器一分js源碼
    此時這個js源碼就是作為一個client, 他在瀏覽器上直接和authorizationserver交互,
    那么協議交互數據和獲取的憑證(比如code,access token)則直接就在瀏覽器上完成, 也所以誰都看得見.

  • 本地應用(native application)

   這種本地應用是一種安裝並運行在資源owner所使用設備上的public client.協議數據和credential對owner來說可以訪問獲得.
   一般這種情況下, 應用中包含的任何客戶端授權credential都是可以提取出來的。
   另一方面, 對於動態簽發的credential比如access token或者refresh tokent, 是可以接收一個可接受的保護等級.
   至少,要保證這些憑據不會被與應用交互的惡意服務器攻擊。另外在某些平台上,這些憑據同樣也需要免受位於同一設備上的應用程序的攻擊。

 

2.2 客戶端id(Client Identifier)

授權服務器給前來注冊的客戶端頒發了一個客戶端標識符(client id) -- 一個用來代表client所提供的注冊信息的唯一字符串。
客戶端標識符不是密文; 它會暴露給資源所有者,但是不允許僅使用它來進行client授權。該id對授權服務器來說,是唯一的。

客戶端標識符字符串的大小本文不做要求, 所以客戶應避免對標識符大小做校驗。授權服務器應該將其頒發的id大小形成文本方便使用者閱讀。

wxy: 首先要明確,這個id是由授權服務器頒發的,用來指代來注冊的客戶端,確切的說是用來標識客戶端提供的一坨注冊信息(當然也包括客戶端的url等),

 

2.3 客戶認證(Client Authentication)

如果客戶端為機密類型的(confidential client), 則客戶端和授權服務器需要建立一個認證機制才能滿足授權服務器的安全性要求。
授權服務器可以接受任何形式的客戶端身份驗證同時滿足他的安全要求。

機密類型客戶端通常會發布(或建立)一組客戶端憑據, 用於和授權服務器進行身份認證(例如,密碼,公鑰/私鑰對)。

授權服務器也可以與公共客戶(public client)建立客戶端認證方法。但是,授權服務器不得將此用於識別(identifying)客戶。

客戶端在每個請求中不得使用超過一種身份驗證方法。

wxy: 這個針對客戶的認證是一個廣義的要求, 即要求授權服務器對發起請求的client進行認證,包括協議flow的各個階段都適用,
只要是授權服務器的要求...,這里面的授權服務器(authorization
server)也是廣義的, 見下面的兩種終端(endpoint)

 

2.4. 未注冊客戶端(Unregistered Clients)

本規范不排除使用未注冊的客戶端。但是,使用此類客戶端超出了此范圍規范,並需要進行額外的安全分析和審查它的互操作性影響

wxy: 客戶端具體如何注冊並不是協議的一部分, 這個動作是為了讓授權服務器中提前就有client的身份信息,如此就可以更加安全的進行授權操作.
所以,只要滿足rfc的要求: client需要提前在server端進行注冊,那么具體如何實現則不要求。

 

3. 協議終端(Protocol Endpoints)

在整個協議制定的交互中, 使用了2個授權服務終端和1個客戶終端, 如下:

1.  2個授權服務終端(提供HTTP資源):

  o  授權終端(Authorization endpoint) - 用於客戶端通過user-agent的重定向來從資源owner那邊獲取授權.
      (used by the client to obtain authorization from the resource owner via user-agent redirection.)

  o Token終端(Token endpoint) - 用於客戶端使用所授予的權限來交換得到access token, 通常使用客戶端認證.

2. 一個客戶終端(client endpoint):

  o 重定向終端(Redirection endpoint) - 授權服務器通過owner的user-agent, 向這個其回復含有授權憑據的應答.
          (used by the authorization server to return responses containing authorization credentials to the client via the resource owner user-agent.)

不是所有權限授予都使用這兩部分終端, 當然對於擴展權限類型還可能根據需要定義額外的endpoints

wxy: 所謂endpoints, 其實可以理解成一個地址/api/路由(對應的目的地), 開發過http應用的人都知道, 都有一顆路由樹, 每條路由對應一個api, 一個功能handler,
   所以, 在這種體系下, endpoint即終端, 正是體現了一種不同的"目的地"的概念, 在本協議中, 典型的包含了三個地址

 

3.1 Authorization Endpoint

授權端點用於與資源owner進行交互, 並取得owner的授權。授權服務器必須首先驗證資源owner的身份。
具體使用什么方式則不規定, 可以是用戶名和密碼登錄,可以是會話cookie.

至於客戶如何知道授權端點或者說是授權服務器的url, 則不歸本rfc管,但典型的方式是在服務文檔中提供.

  The endpoint URI MAY include an "application/x-www-form-urlencoded" formatted query component,
  which MUST be retained when adding additional query parameters. The endpoint URI MUST NOT include a fragment component.

由於對授權端點的請求導致用戶身份驗證和明文憑證的傳輸(在HTTP響應里),所以授權服務器必須要求在向本服務器發送請求時使用TLS

授權服務器必須支持HTTP "GET"方法, 也可以支持"POST"方法。


不帶值發送的參數必須被視為從請求中省略。授權服務器必須忽略無法識別的請求參數。請求和響應參數不得超過一次。

3.1.1 關於應答的類型

授權端點是用在授權碼(authorization code)和隱式授權(implicit grant)這兩種形式中.
客戶端會通過response_type這個字段來告知授權服務器其希望使用的grant類型。

response_type: 必選字段, 如果是授權碼類型, 則取值"code", 如4.1.1節; 如果是獲取access token(隱式授權類型), 則取值"token", 如4.2.1節;
       也可以是一個已經注冊了的擴展類型值, 詳見第8.4節所述.

擴展響應類型, 是一個由空格(%x20)分隔的列表值,值的順序無關緊要(例如"a b"與"b a"相同)。至於這種復合響應類型的含義, 則由其各自的規范定義。

如果授權請求中缺少"response_type"參數, 或者是無法識別的類型值,則授權服務器必須返回一個錯誤應答,如第4.1.2.1節所述。


3.1.2. 關於重定向端點(Redirection Endpoint)

在完成與資源owner的交互后, 授權服務器會將owner的user-agent引導回客戶端,使用的就是這個重定向地址(客戶端的redirection endpoint),
而該地址是於之前客戶端與授權服務器處理注冊流程或授權流程時建立的。

重定向端點URI必須是一個絕對URI, 詳細見4.3節中的定義。端點URI可以包含一個"application/x-www-form-urlencoded"格式...
針對這個URI有如下的要求:

1. 端點請求的機密性的要求(Endpoint Request Confidentiality)
 要求使用tls....

2. 哪些需要進行注冊(Registration Requirements)
    授權服務器必須要求如下種類的客戶端注冊其重定向URI:
  o 公共客戶端.
  o 使用隱式授予類型的機密客戶端.

 授權服務器應該要求所有客戶端先注冊其重定向端點,然后再使用授權端點。

 授權服務器應該要求客戶端提供完整的重定向URI(客戶端可以使用"state"請求參數以實現每個請求的自定義)。如果無法注冊完整的重定向URI,
 授權服務器應該要求注冊URI的scheme, authority, and path (如此可以允許客戶端在請求授權時, 動態變化查詢語句).

 授權服務器可以允許客戶端注冊多個重定向端點。

 缺少重定向URI可能導致通過將授權端點作為開放重定向器而產生的攻擊,詳見10.15節中描述。

3. 端點的內容(Endpoint Content)
 重定向到客戶端端點的請求通常會得到一個HTML文本響應, 然后由user-agent來處理。
 所以如果HTML響應直接作為重定向請求的結果, 那么HTML文本中包含的所有腳本都將完整執行,且完全有權限訪問重定向URI及其包含的憑據。

 客戶端不應在重定向端點響應(redirection endpoint response)中包含任何第三方腳本(例如,第三方分析,社交插件,廣告網絡)。
 相反, 它應該從URI中提取憑證, 然后在沒有暴露credential的情況下將user-agent再次重定向到另一個端點(URI中或其他地方指定的)。
 如果有第三方腳本包含在內,客戶端必須確保其自己的腳本(用於從URI中提 取和刪除憑據)會先執行。

wxy: 所謂重定向, 即授權服務器帶着憑證信息訪問之前指定的Redirection url交給瀏覽器
  (這是一個特殊的http應答么? 一個來自授權服務器給瀏覽器的?)
  所以, 當瀏覽器訪問這個重定向url也即向client發出請求后, 會得到client返回的應答,通常是一個html網頁, 由user-agent即瀏覽器負責處理處理。
  需要注意的是,client收到請求后應該第一時間提取給自己的credential, 同時返回的這個html應答中不能包括腳本程序.


3.2. 令牌端點(Token Endpoint)

客戶端通過向token endpoint提供授權grant或refresh token, 進而獲取access token。
token endpoint需要與所有授權grant一起使用,除了隱式授權類型(因為直接頒發了access token)。

至於客戶端是如何獲取token endpoint的地址則不在本文檔的討論范圍中, 通常這個地址會由服務文檔提供。

endpoint的urI可以包含"application/x-www-form-urlencoded"....

由於對token endpoint的請求會導致明文credential的傳輸(在http請求和應答中), 所以授權服務器必須要使用tls...

客戶端必須要使用POST方法去請求access token

請求中如果攜帶了沒有值的參數, 則應該被忽略, 同時必須忽略無法識別的請求參數。請求和響應參數不得重復。

3.2.1 客戶端的認證(Client Authentication)

在2.3章節中已經說過, 機密型客戶端或其他類型客戶端在向令牌端點發出請求時,
其使用的客戶憑據必須經由授權服務器進行身份認證才行。這么做的原因是:

 o 強制將refresh token和授權碼綁定到所簽發給的客戶端上
  。對於當授權碼會通過一個不安全的通道傳輸到重定向 endpoint,
  或重定向URI具有尚未完全注冊時, 客戶端身份驗證顯得至關重要。

 o 可以通過禁用客戶端或更改其憑據, 來恢復受感染的客戶端,
  從而防止攻擊者濫用盜取的refresh token。
  更改一組客戶憑證比吊銷一整套refresh token要快得多。

 o 實施身份認證管理的最佳實踐是,定期的憑證輪換。
  整套輪換機制可能使得設置refresh token, 刷新令牌可能具有挑戰性,而單組的憑證輪換機制則會非常容易。

客戶端在向token endpoint發送請求時,可以使用"client_id"參數來標識自己。在發向token endpoint的
"authorization_code""grant_type"請求中, 一個未經身份驗證的客戶端必須發送其"client_id",
這樣可以避免不小心接收了本來是簽發給其他具有不同"client_id"的客戶端的授權碼。(針對受保護資源並沒有提供額外的保護機制)。

 

3.3 訪問token的使用范圍(Access Token Scope)

authorization 和 token endpoints允許客戶端通過使用"scope"參數來指定訪問請求的范圍。
再然后,授權服務器通過使用"scope"響應參數來通知客戶端其頒發的access token的范圍。

scope參數的值使用一個以空格為分隔符的字符串列表表達式,區分大小寫的。字符串由授權服務器定義。
如果值包含多個以空格分隔的字符串,它們的順序無關緊要,並且每個字符串都會添加一個所請求范圍的其他訪問范圍。
  scope = scope-token *( SP scope-token )
  scope-token = 1*( %x21 / %x23-5B / %x5D-7E )

  ...

小結

從http請求應答的維度,將整個協議的交互串聯起來: 三個endpoint的交互
  首先,客戶端端請求Authorization endpoint/url獲取授權,
  然后, 假設同意授權, 授權服務器將grant憑據以及client endpoint/url交給瀏覽器讓其重定向訪問該url, 進而客戶端取得grant
  最后,客戶端請求Token endpoint/url換取access token

      ---請求with redirect uri---> Authorization endpoint
      <----應答 and redirect-----
  瀏覽器
      ------------請求---------> Redirection endpoint
      <----------應答----------    /client    <------------------> Token endpoint

一般, 授權服務器Authorization Server是廣義的, 其提供了2種功能, 於是對應2個路由/api/endpoint.

對於重定向URI, 是client在向授權服務器注冊的時候提供給他的,用來在授權服務器生成credential(包括授權碼,access token等)后,知道將些憑證交給誰,
通常是借助user-agent攜帶credential信息重定向訪問該URI, 而作為credential的接收者同時作為一次http請求的服務方,還要給user-agent(瀏覽器)一個應答,
那么這個應答一定要把憑證信息剝離下來....


4.獲得授權(Obtaining Authorization)

4.1授權碼方式詳解(Authorization Code Grant)

授權碼方式包括獲取access token和refresh token, 同時對受信任客戶端進行了優化。
於這是一套基於重定向的流程,因此客戶端必須具備與資源owner的user-agent(通常是是web瀏覽器)進行交互的能力,
還要具備接收來自authorization server的進向請求(通過重定向的方式).

完整流程如下:

 

注意:用來描述步驟(A)(B)(C)的三條線由於涉及到user-agent所以被分隔成2個part

 

二. 一實際應用場景

一個web應用(web application類型的client),
需要能夠拉取某個用戶(resource owner)在github上(authorization server)的代碼(protected resource).

結合實際場景的流程解析:

(A) 整個流程始於客戶端將資源owner的user-agent引導到授權端點開始,客戶端會提供它的client id, scope, local state和redirection URI,
   其中redirection URI表示一旦授權通過(或拒絕), 則授權服務器會將user-agent發送到這個地址上(重定向到這個地址上).

    wxy: 根據圖示可知, A步驟分兩個part: client --引導--> user-agent;
                            user-agent --訪問--> Authorization server;
  

    實際場景: 首先, 這個web應用呈現在瀏覽器上的頁面中已經集成了要發送給a s的關鍵信息(client id等),
    然后, 一旦特定操作觸發,頁面上的js(或其他方式)會讓瀏覽器直接向github的地址發出請求
    請求中會攜帶client id, scope, local state和redirection URI,等

(B) 授權服務器會對資源owner進行身份驗證(通過user-agent), 並確定owner是允許還是拒絕客戶端的訪問請求。

    實際場景: github會返回授權頁面給瀏覽器, 提示owner輸入賬號密碼等信息

(C) 假設資源owner授予了訪問權限, 則授權服務器使用之前提供的重定向URI(可以是本次請求的時或是客戶端注冊時)
   將user-agent重定向回客戶端. 重定向URI包含一個授權代碼和客戶端提供的任何本地狀態較早。

    wxy: 根據前面知道, 客戶端注冊的時候也會提供重定向uri, 同樣要求向as發授權請求還是要攜帶redirection URI,
       當然,這中間client id是一個client唯一的身份標識。
       最后,瀏覽器會拼接as返回的授權碼到redirection uri上來訪問這個地址

    實際場景: 首先, as為client生成了授權碼:code, 然后帶着redirection uri(即client的某個api)告訴瀏覽器該重定向了
          於是, 瀏覽器帶着code訪問client

(D) 客戶端攜帶上一步中獲得的授權碼, 去授權服務器的令牌端點(token endpoint)請求access token.
在請求中, 授權服務器會對客戶端進行認證, 而客戶端為了認證通過也會將用於獲得授權碼的重定向URI也包含進來。

實際場景: 我的應用拿着code 和 redirection uri訪問github的token api

(E) 授權服務器對客戶端進行身份驗證,校驗授權碼,並確保本次接收的重定向URI與步驟(C)中接收的匹配。
如果一切驗證通過, 則授權服務器將回復access token, 可選的還有refresh token.

    實際場景: github進過一些列驗證, 返回給我的應用一個token.


wxy: 如上的流程實際上是省略了注冊的環節,因為只有注冊了才會得到一個client id, 另外雖然本文檔中並沒有明確說明在發出授權請求的時候,
會驗證攜帶的redirect URI, 但是結合一個開源的實現,加上常規理解,必然應該對授權請求中攜帶的redirect URI進行校驗,只有符合注冊時的才可以,
畢竟二者使用的是相同的client id.


免責聲明!

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



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