OAuth2.0認證和受權原理(續)

客戶端四種受權模式

 

客戶端必須獲得用戶的受權(authorization grant),才能得到令牌(access token)。OAuth 2.0定義了四種受權方式。json

  • 受權碼模式(authorization code)瀏覽器

  • 簡化模式(implicit)緩存

  • 密碼模式(resource owner password credentials)服務器

  • 客戶端模式(client credentials)app

1、受權碼模式

受權碼模式(authorization code)是功能最完整、流程最嚴密的受權模式。它的特色就是經過客戶端的後臺服務器,與"服務提供商"的認證服務器進行互動。url

受權碼模式

它的步驟以下:操作系統

(A)用戶訪問客戶端,後者將前者導向認證服務器。3d

(B)用戶選擇是否給予客戶端受權。code

(C)假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(redirection URI),同時附上一個受權碼。orm

(D)客戶端收到受權碼,附上早先的"重定向URI",向認證服務器申請令牌。這一步是在客戶端的後臺的服務器上完成的,對用戶不可見。

(E)認證服務器覈對了受權碼和重定向URI,確認無誤後,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)。

下面是上面這些步驟所須要的參數。

A步驟中,客戶端申請認證的URI,包含如下參數:

  • response_type:表示受權類型,必選項,此處的值固定爲"code"

  • client_id:表示客戶端的ID,必選項

  • redirect_uri:表示重定向URI,可選項

  • scope:表示申請的權限範圍,可選項

  • state:表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值。

下面是一個例子。

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

C步驟中,服務器迴應客戶端的URI,包含如下參數:

  • code:表示受權碼,必選項。該碼的有效期應該很短,一般設爲10分鐘,客戶端只能使用該碼一次,不然會被受權服務器拒絕。該碼與客戶端ID和重定向URI,是一一對應關係。

  • state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。

下面是一個例子。

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

D步驟中,客戶端向認證服務器申請令牌的HTTP請求,包含如下參數:

  • grant_type:表示使用的受權模式,必選項,此處的值固定爲"authorization_code"。

  • code:表示上一步得到的受權碼,必選項。

  • redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該參數值保持一致。

  • client_id:表示客戶端ID,必選項。

下面是一個例子。

POST /token HTTP/1.1Host: server.example.comAuthorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

E步驟中,認證服務器發送的HTTP回覆,包含如下參數:

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

  • token_type:表示令牌類型,該值大小寫不敏感,必選項,能夠是bearer類型或mac類型。

  • expires_in:表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。

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

  • scope:表示權限範圍,若是與客戶端申請的範圍一致,此項可省略。

下面是一個例子。

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

從上面代碼能夠看到,相關參數使用JSON格式發送(Content-Type: application/json)。此外,HTTP頭信息中明確指定不得緩存。

2、簡化模式

簡化模式(implicit grant type)不經過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,跳過了"受權碼"這個步驟,所以得名。全部步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不須要認證。

簡化模式

它的步驟以下:

(A)客戶端將用戶導向認證服務器。

(B)用戶決定是否給於客戶端受權。

(C)假設用戶給予受權,認證服務器將用戶導向客戶端指定的"重定向URI",並在URI的Hash部分包含了訪問令牌。

(D)瀏覽器向資源服務器發出請求,其中不包括上一步收到的Hash值。

(E)資源服務器返回一個網頁,其中包含的代碼能夠獲取Hash值中的令牌。

(F)瀏覽器執行上一步得到的腳本,提取出令牌。

(G)瀏覽器將令牌發給客戶端。

下面是上面這些步驟所須要的參數。

A步驟中,客戶端發出的HTTP請求,包含如下參數:

  • response_type:表示受權類型,此處的值固定爲"token",必選項。

  • client_id:表示客戶端的ID,必選項。

  • redirect_uri:表示重定向的URI,可選項。

  • scope:表示權限範圍,可選項。

  • state:表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值。

下面是一個例子。

    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

C步驟中,認證服務器迴應客戶端的URI,包含如下參數:

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

  • token_type:表示令牌類型,該值大小寫不敏感,必選項。

  • expires_in:表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。

  • scope:表示權限範圍,若是與客戶端申請的範圍一致,此項可省略。

  • state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。

下面是一個例子。

     HTTP/1.1 302 Found
     Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
               &state=xyz&token_type=example&expires_in=3600

在上面的例子中,認證服務器用HTTP頭信息的Location欄,指定瀏覽器重定向的網址。注意,在這個網址的Hash部分包含了令牌。

根據上面的D步驟,下一步瀏覽器會訪問Location指定的網址,可是Hash部分不會發送。接下來的E步驟,服務提供商的資源服務器發送過來的代碼,會提取出Hash中的令牌。

3、密碼模式

密碼模式(Resource Owner Password Credentials Grant)中,用戶向客戶端提供本身的用戶名和密碼。客戶端使用這些信息,向"服務商提供商"索要受權。

在這種模式中,用戶必須把本身的密碼給客戶端,可是客戶端不得儲存密碼。這一般用在用戶對客戶端高度信任的狀況下,好比客戶端是操做系統的一部分,或者由一個著名公司出品。而認證服務器只有在其餘受權模式沒法執行的狀況下,才能考慮使用這種模式。

密碼模式

它的步驟以下:

(A)用戶向客戶端提供用戶名和密碼。

(B)客戶端將用戶名和密碼發給認證服務器,向後者請求令牌。

(C)認證服務器確認無誤後,向客戶端提供訪問令牌。

B步驟中,客戶端發出的HTTP請求,包含如下參數:

  • 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

C步驟中,認證服務器向客戶端發送訪問令牌,下面是一個例子。

     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、客戶端模式

客戶端模式(Client Credentials Grant)指用戶直接向客戶端註冊,客戶本身請求"服務提供商"提供服務。

它的步驟以下:

(A)客戶端向認證服務器進行身份認證,並要求一個訪問令牌。

(B)認證服務器確認無誤後,向客戶端提供訪問令牌。

A步驟中,客戶端發出的HTTP請求,包含如下參數:

  • granttype:表示受權類型,此處的值固定爲"clientcredentials",必選項。

  • scope:表示權限範圍,可選項。

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

認證服務器必須以某種方式,驗證客戶端身份。

B步驟中,認證服務器向客戶端發送訪問令牌,下面是一個例子。

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

更新令牌

若是用戶訪問的時候,客戶端的"訪問令牌"已通過期,則須要使用"更新令牌"申請一個新的訪問令牌。

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

  • granttype:表示使用的受權模式,此處的值固定爲"refreshtoken",必選項。

  • 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
相關文章
相關標籤/搜索