OAuth2.0詳解(受權模式篇)

OAuth2.0有五種受權模式。json

(1)受權碼模式(Authorization Code) 
(2)受權碼簡化模式(Implicit) 
(3)Pwd模式(Resource Owner Password Credentials) 
(4)Client模式(Client Credentials) 
(5)擴展模式(Extension)瀏覽器

注:文中的client,可理解爲瀏覽器或APP。安全

但不論哪一種模式,都是爲了從認證服務器獲取Access Token,用來訪問資源服務器。 
而申請Access Token,須要提交相應信息。例如,client_ID(我是誰),response_type或grant_typt(申請哪一種模式),scope(申請哪些權限,由受權服務器定義),redirect_uri(申請結果跳轉至哪兒)等。固然不一樣的模式,提交信息內容也不一樣。服務器

咱們先從簡單的模式開始。由於簡單模式,申請流程短,安全級別較低,我的感受可用場景很少。微信

(一)Client模式
先上流程圖。app

該模式下,並不存在對個體用戶受權的行爲,被受權的主體爲client。所以,該模式可用於對某類用戶進行集體受權。ide

申請該模式時,須要在HTTP request entity-body中提交如下信息。this

grant_type:
         REQUIRED.  Value MUST be set to "client_credentials".url

scope:
         OPTIONAL.  The scope of the access request
1
2
3
4
5
固然,能夠根據受權服務器的實現,提交其它必要信息。 
若申請成功,服務器將返回access token和token有效時間。3d

附規範中的例子。 
Request:

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

     grant_type=client_credentials
1
2
3
4
5
6
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"
     }
1
2
3
4
5
6
7
8
9
10
11
注:expires_in爲token有效時長,單位爲秒。

(二)Pwd模式


該模式下,須要用戶將自身的account ID和password交由client,client將使用它們來申請access token,整個過程會將用戶信息暴露。所以,除非client十分可靠(例如硬件設備,系統APP),不然,不建議使用該模式。

申請該模式時,須要在HTTP request entity-body中提交如下信息。

   grant_type:
         REQUIRED.  Value MUST be set to "password".

   username:
         REQUIRED.  The resource owner username.

   password:
         REQUIRED.  The resource owner password.

   scope:
         OPTIONAL.  The scope of the access request
1
2
3
4
5
6
7
8
9
10
11
申請成功後,受權服務器將返回access token和token有效時間,以及可選的refresh token,用於在access token過時時進行token更新。

附規範中的例子。 
Request:

     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
1
2
3
4
5
6
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"
     }
1
2
3
4
5
6
7
8
9
10
11
12
(三)受權碼模式


該模式是五種受權中最囉嗦的。從流程上看,申請分爲兩個階段。首先,須要申請Authorization Code,以後,使用Authorization Code來申請Access Token。

咱們以優酷爲例,講述流程。 
(A)優酷向用戶展現,「我」能夠支持QQ、微信、支付寶等第三方式登陸。用戶選擇其中一種,例如QQ,則跳轉至QQ界面(User-Agent),一般爲WEB界面。此時,若用戶未登陸,則要求用戶登陸,若已登陸,則詢問是否受權,以及展現受權後會得到哪些權限。 
(B)用戶點擊受權,觸發申請。 
(C)假設受權經過,QQ認證服務器將用戶導向優酷事先指定的」重定向URI」(redirection URI),同時附上一個Authorization Code。 
(D)優酷收到受權碼,附上早先的」重定向URI」,向認證服務器申請Access Token。這一步是在優酷的後臺的服務器上完成的,對用戶不可見。 
(E)認證服務器覈對了受權碼和重定向URI,確認無誤後,向優酷發送訪問令牌(access token)和更新令牌(refresh token)。

Authorization Code只能使用一次,且有時間限制,規範建議爲10分鐘。

申請Authorization Code時,須要在URI的query component中附加如下信息

   response_type:
         REQUIRED.  Value MUST be set to "code".

   client_id:
         REQUIRED.  The client identifier

   redirect_uri:
         OPTIONAL.  

   scope:
         OPTIONAL.  The scope of the access request

   state:
         RECOMMENDED.  An opaque value used by the client to
         maintain state between the request and callback.  The
         redirecting the user-agent back to the client.  The 
         parameter SHOULD be used for preventing cross-site
         request forgery.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Authorization Code返回時,URI的query component中的附加信息以下

 code:
         REQUIRED.  The authorization code generated by the
         authorization server.  The authorization code MUST of 
         expire shortly after it is issued to mitigate the risk 
         of leaks.  A maximum authorization code lifetime of 10 
         minutes is RECOMMENDED.  The client MUST NOT use the 
         authorization code more than once.  If an authorization 
         code is used more than once, the authorization server 
         MUST deny the request and SHOULD revoke (when possible) 
         all tokens previously issued based on that authorization 
         code.  The authorization code is bound to the client 
         identifier and redirection URI.

   state:
         REQUIRED if the "state" parameter was present in the 
         client authorization request.  The exact value received 
         from the client.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
使用Authorization Code申請Access Token時,須要在HTTP request entity-body中提交如下信息。

   grant_type:
         REQUIRED.  Value MUST be set to "authorization_code".

   code:
         REQUIRED.  The authorization code received from the
         authorization server.

   redirect_uri:
         REQUIRED, if the "redirect_uri" parameter was included 
         in the authorization request, and their values MUST be 
         identical.

   client_id:
         REQUIRED, if the client is not authenticating with the
         authorization server.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
申請成功後,受權服務器將返回access token和token有效時間,以及可選的refresh token。

附規範中的例子。 
Request Authorization Code:

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
1
2
Authorization Code Response:

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

     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
1
2
3
4
5
6
7
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"
     }
1
2
3
4
5
6
7
8
9
10
11
12
(四)受權碼簡化模式


在受權碼模式中,Authorization Code和Access Token都由受權服務器生成和驗證,而最終只用到Access Token,這讓Authorization Code顯得無足輕重。所以,受權碼簡化模式,去掉了Authorization Code的申請流程,從而經過User-Agent(Browser)直接申請Access Token。

咱們還以優酷爲例,講述流程。 
(A)優酷向用戶展現,「我」能夠支持QQ、微信、支付寶等第三方式登陸。用戶選擇其中一種,例如QQ,則跳轉至QQ界面(User-Agent),一般爲WEB界面。此時,若用戶未登陸,則要求用戶登陸,若已登陸,則詢問是否受權,以及展現受權後會得到哪些權限。 
(B)用戶點擊受權,觸發申請。 
(C)假設受權經過,QQ認證服務器將用戶導向優酷事先指定的」重定向URI」(redirection URI),同時附上Access Token。 
(D)QQ界面(User-Agent)收到重定向響應後,向優酷服務器提出請求,表示想提取URI中的Access Token。 
(E)優酷服務器返回帶有解析腳本的頁面,用於解析重定向URI fragment中的Access Token。 
(F)User-Agent使用解析腳本,獲取Access Token。 
(G)User-Agent將Access Token轉交給優酷。

申請Access Token時,須要在URI的query component中附加如下信息

   response_type:
         REQUIRED.  Value MUST be set to "token".

   client_id:
         REQUIRED.  The client identifier.

   redirect_uri:
         OPTIONAL.

   scope:
         OPTIONAL.  The scope of the access request.

   state:
         RECOMMENDED.  An opaque value used by the client to 
         maintain state between the request and callback.  The 
         authorization server includes this value when 
         redirecting the user-agent back to the client.  The 
         parameter SHOULD be used for preventing cross-site 
         request forgery.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Access Token返回時,URI的query component中的附加信息以下

   access_token:
         REQUIRED.  The access token issued by the authorization 
         server.

   token_type:
         REQUIRED.  The type of the token issued.  Value is case 
         insensitive.

   expires_in:
         RECOMMENDED.  The lifetime in seconds of the access 
         token.  For example, the value "3600" denotes that the 
         access token will expire in one hour from the time the 
         response was generated. If omitted, the authorization 
         server SHOULD provide the expiration time via other 
         means or document the default value.

   scope:
         OPTIONAL, if identical to the scope requested by the 
         client; otherwise, REQUIRED.  The scope of the access 
         token.

   state:
         REQUIRED if the "state" parameter was present in the 
         client authorization request.  The exact value received 
         from the client.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
注:受權碼簡化模式,不生成refresh token。

附規範例子。 
Access Token Request:

GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
1
2
Access Token Response:

HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
               &state=xyz&token_type=example&expires_in=3600
1
2
3
注:此處存在質疑。規範例子中URI不一致,我的認爲Response中的URI應爲:https://client.example.com/cb。若同窗有其餘看法,望賜教。

(五)擴展模式
擴展模式,實際上是一種自定義模式。規範中僅對「grant type」參數提出了須爲URI的要求。對於其餘申請數據,能夠根據需求進行自定義。

附規範例子。

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

     grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Asaml2-      bearer&assertion=PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU      [...omitted for brevity...]aG5TdGF0ZW1lbnQ-PC9Bc3NlcnRpb24-  

相關文章
相關標籤/搜索