OAuth 2.0 授權(quán)模式

OAuth 2.0 是什么?

OAuth 2.0 是一個(gè)授權(quán)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn)

角色

Resource Owner:資源所有者,既用戶
User Agent:用戶代理
Authorization Server:既提供第三方登錄服務(wù)的服務(wù)器
Client:第三方應(yīng)用,我們的應(yīng)用就是一個(gè)client

客戶端的授權(quán)模式類型

  1. 授權(quán)碼模式
  2. 隱式授權(quán)模式
  3. 密碼模式
  4. 客戶端模式

授權(quán)碼模式

 +----------+
 | Resource |
 |   Owner  |
 |          |
 +----------+
      ^
      |
     (B)
 +----|-----+          Client Identifier      +---------------+
 |         -+----(A)-- & Redirection URI ---->|               |
 |  User-   |                                 | Authorization |
 |  Agent  -+----(B)-- User authenticates --->|     Server    |
 |          |                                 |               |
 |         -+----(C)-- Authorization Code ---<|               |
 +-|----|---+                                 +---------------+
   |    |                                         ^      v
  (A)  (C)                                        |      |
   |    |                                         |      |
   ^    v                                         |      |
 +---------+                                      |      |
 |         |>---(D)-- Authorization Code ---------'      |
 |  Client |          & Redirection URI                  |
 |         |                                             |
 |         |<---(E)----- Access Token -------------------'
 +---------+       (w/ Optional Refresh Token)

1.授權(quán)請(qǐng)求
比如你想登錄gitlab,并且想利用三方授權(quán)登錄,比如谷歌賬號(hào),當(dāng)你點(diǎn)擊谷歌圖標(biāo)的時(shí)候,會(huì)首先發(fā)起一個(gè)請(qǐng)求,會(huì)帶上以下參數(shù),向授權(quán)服務(wù)器發(fā)送授權(quán)請(qǐng)求:

response_type:表示授權(quán)類型,必選項(xiàng)
client_id:表示客戶端的ID,必選項(xiàng),一般是在授權(quán)服務(wù)器上申請(qǐng)應(yīng)用的時(shí)候,頒發(fā)的
redirect_uri:重定向的 uri
scope:表示申請(qǐng)的權(quán)限范圍
state:表示客戶端的當(dāng)前狀態(tài),可以是任意值,認(rèn)證服務(wù)器會(huì)原封不動(dòng)的返回這個(gè)值

下面是一個(gè)例子:

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

授權(quán)服務(wù)器驗(yàn)證該請(qǐng)求,確保所有的參數(shù)提交且有效,授權(quán)服務(wù)器會(huì)引導(dǎo)用戶進(jìn)入授權(quán)頁面

2.當(dāng)用戶點(diǎn)擊確定授權(quán)時(shí),授權(quán)服務(wù)器會(huì)返回授權(quán)碼(code)和狀態(tài)參數(shù)(state),返回請(qǐng)求到相應(yīng)的回調(diào)地址(redirect_uri)。至此,用戶的主動(dòng)行為已經(jīng)結(jié)束。
3.第三方應(yīng)用,也就是我們的客戶端,在拿到授權(quán)碼之后會(huì)直接向授權(quán)服務(wù)器請(qǐng)求訪問令牌,參數(shù)如下:

grant_type:授權(quán)模式,必選項(xiàng),值  "authorization_code"
code:從授權(quán)服務(wù)器收到的授權(quán)碼
redirect_uri:回調(diào)地址
client_id:標(biāo)識(shí)應(yīng)用ID
client_secret:授權(quán)服務(wù)器頒發(fā)的密鑰

授權(quán)服務(wù)器驗(yàn)證通過后會(huì)返回如下參數(shù):

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

至此整個(gè)授權(quán)碼流程結(jié)束。

需要注意的幾個(gè)問題
  • 重定向 redirect_uri uri 整個(gè)授權(quán)過程都是一樣的

  • 授權(quán)過程只是授權(quán):
    比如,你想用 "支付寶" 授權(quán)登錄 "優(yōu)酷" ,整個(gè)授權(quán)的過程只是支付寶驗(yàn)證用戶授權(quán),返回一個(gè) openId 和 支付寶允許給優(yōu)酷的一些用戶信息,優(yōu)化拿到 openId可以直接上傳服務(wù)端注冊(cè),至此整個(gè)授權(quán)流程結(jié)束。后面優(yōu)酷相關(guān)聯(lián)的資源獲取和授權(quán)沒有任何關(guān)聯(lián)了。優(yōu)酷會(huì)對(duì)這個(gè) openId和賬號(hào)做唯一映射,這樣下次還用支付寶授權(quán)登錄,優(yōu)酷的服務(wù)端不會(huì)在創(chuàng)建新的賬號(hào)給該用戶,即不需要用戶密碼的一鍵登錄。

  • 為什么整個(gè)授權(quán)流程不直接返回 access_token 而是要經(jīng)過中間步驟先要獲取授權(quán)碼 code ,在根據(jù)授權(quán)碼再次獲取 access_token ?
    最直接的答案是安全,code有效期比較短,而且一個(gè)code只能換取一次access_token即失效。獲取code的請(qǐng)求是用戶主動(dòng)授權(quán)之后獲取的從這里截止,用戶的主動(dòng)行為結(jié)束。
    獲取參數(shù)不包含 appsecret,請(qǐng)求回來的code回立馬再次發(fā)起請(qǐng)求,這次請(qǐng)求會(huì)帶上appsecret,授權(quán)服務(wù)器驗(yàn)證并返回 access_token

隱式授權(quán)模式

+----------+
 | Resource |
 |  Owner   |
 |          |
 +----------+
      ^
      |
     (B)
 +----|-----+          Client Identifier     +---------------+
 |         -+----(A)-- & Redirection URI --->|               |
 |  User-   |                                | Authorization |
 |  Agent  -|----(B)-- User authenticates -->|     Server    |
 |          |                                |               |
 |          |<---(C)--- Redirection URI ----<|               |
 |          |          with Access Token     +---------------+
 |          |            in Fragment
 |          |                                +---------------+
 |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
 |          |          without Fragment      |     Client    |
 |          |                                |    Resource   |
 |     (F)  |<---(E)------- Script ---------<|               |
 |          |                                +---------------+
 +-|--------+
   |    |
  (A)  (G) Access Token
   |    |
   ^    v
 +---------+
 |         |
 |  Client |
 |         |
 +---------+

和 授權(quán)碼請(qǐng)求一樣,首先你會(huì)發(fā)起一個(gè)授權(quán)請(qǐng)求,驗(yàn)證參數(shù)

  1. 授權(quán)請(qǐng)求:
response_type:表示授權(quán)類型,此處固定值為 token
client_id:客戶端標(biāo)識(shí)
redirect_uri:重定向 uri
scope:訪問的權(quán)限范圍
state:表示客戶端的當(dāng)前狀態(tài),可以是任意值,認(rèn)證服務(wù)器會(huì)原封不動(dòng)的返回

客戶端發(fā)起 HTTP 請(qǐng)求,如下:

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

2.授權(quán)服務(wù)器會(huì)驗(yàn)證該請(qǐng)求,確保所有的參數(shù)已提交且有效。授權(quán)服務(wù)器驗(yàn)證請(qǐng)求參數(shù)中的uri和客戶端提交的重定向的uri保持一致。
如果,該請(qǐng)求是有效的,授權(quán)服務(wù)器驗(yàn)證對(duì)資源所有者進(jìn)行身份驗(yàn)證并展示授權(quán)頁面給用戶。
用戶同意授權(quán)請(qǐng)求時(shí),授權(quán)服務(wù)器回返回如下參數(shù):

access_token:授權(quán)服務(wù)器頒發(fā)的訪問令牌
token_type:令牌類型
expires_in:過期時(shí)間
scope:表示授權(quán)權(quán)限范圍
state:表示客戶端的當(dāng)前狀態(tài),可以是任意值,認(rèn)證服務(wù)器會(huì)原封不動(dòng)的返回這個(gè)值

這些參數(shù),拼接在重定向 uri 地址的后面

3.第三方應(yīng)用向資源服務(wù)器發(fā)起請(qǐng)求,不包含上一步獲取的access_token
資源服務(wù)器返回一個(gè)網(wǎng)頁(通常是帶有嵌入式腳本的 HTML 文檔),其中的腳本可以提取出令牌,瀏覽器把a(bǔ)ccess_token發(fā)送給客戶端
至此整個(gè)簡(jiǎn)單授權(quán)模式結(jié)束。

隱式授權(quán)和授權(quán)碼授權(quán)的區(qū)別就是,是直接獲取access_token,不需要經(jīng)過code步驟。但是獲取的access_token需要資源服務(wù)器的腳本從第三方代理(既瀏覽器)中提取出來)發(fā)送給客戶端。

密碼模式

 +----------+
 | Resource |
 |  Owner   |
 |          |
 +----------+
      v
      |    Resource Owner
     (A) Password Credentials
      |
      v
 +---------+                                  +---------------+
 |         |>--(B)---- Resource Owner ------->|               |
 |         |         Password Credentials     | Authorization |
 | Client  |                                  |     Server    |
 |         |<--(C)---- Access Token ---------<|               |
 |         |    (w/ Optional Refresh Token)   |               |
 +---------+                                  +---------------+

這種模式用戶必須把"用戶名"和"密碼"給到客戶端,客戶端不得存儲(chǔ)密碼。這通常用在用戶讀客戶端高度信任的情況下。

  1. 資源所有者像客戶端提供他的用戶名和密碼
  2. 當(dāng)發(fā)起請(qǐng)求客戶端向授權(quán)服務(wù)器進(jìn)行身份認(rèn)證
  3. 授權(quán)服務(wù)器對(duì)客戶端進(jìn)行身份驗(yàn)證,驗(yàn)證資源所有者的憑證,如果有效則頒發(fā)訪問令牌。

訪問令牌請(qǐng)求參數(shù):

grant_type:值必須為 "password"
username:資源所有者用戶名
password:資源所有者密碼
scope:客戶端授權(quán)請(qǐng)求范圍

例如:

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

授權(quán)服務(wù)器驗(yàn)證授權(quán)請(qǐng)求通過,參數(shù)如下:

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

客戶端模式

 +---------+                                  +---------------+
 |         |                                  |               |
 |         |>--(A)- Client Authentication --->| Authorization |
 | Client  |                                  |     Server    |
 |         |<--(B)---- Access Token ---------<|               |
 |         |                                  |               |
 +---------+                                  +---------------+

其實(shí),這種模式不屬于授權(quán)模式,是客戶端的行為,而非用戶行為
1.客戶端向授權(quán)服務(wù)器請(qǐng)求驗(yàn)證,并要求一個(gè)訪問令牌
2.授權(quán)服務(wù)器向客戶端進(jìn)行身份驗(yàn)證,如果有效,則頒發(fā)一個(gè)訪問令牌

訪問令牌請(qǐng)求:

grant_type:表示授權(quán)類型,值必須為 "client_credentials"
scope:客戶端的授權(quán)請(qǐng)求反問

如下,請(qǐng)求:

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

授權(quán)服務(wù)器驗(yàn)證該請(qǐng)求,如果請(qǐng)求有效則返回,令牌:

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

刷新訪問令牌

如果,授權(quán)服務(wù)器頒發(fā)了刷新 refresh_token,可以在客戶端發(fā)起刷新 access_token,一般 refresh_token有效期是大于access_token有效期
請(qǐng)求參數(shù)如下:

grant_type:授權(quán)類型,此處必須為 "refresh_token"
refresh_token:頒發(fā)給客戶端的刷新令牌
scope:表示可訪問的權(quán)限范圍

如下 HTTP 請(qǐng)求

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

參考鏈接

http://www.rfcreader.com/#rfc6749
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • OAuth是一個(gè)關(guān)于授權(quán)(authorization)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn),在全世界得到廣泛應(yīng)用,目前的版本是2.0版。...
    謝謝寫閱讀 822評(píng)論 0 1
  • OAuth是一個(gè)關(guān)于授權(quán)(authorization)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn),在全世界得到廣泛應(yīng)用,目前的版本是2.0版。...
    夕望有你閱讀 331評(píng)論 1 2
  • OAuth是一個(gè)關(guān)于授權(quán)(authorization)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn),在全世界得到廣泛應(yīng)用,目前的版本是2.0版。...
    獵人1987閱讀 309評(píng)論 0 0
  • “你大學(xué)過的真是……沒成績(jī)、沒戀愛、沒回憶、沒文化。過得沒心沒肺,倒是真的。”這是昨天晚上和一個(gè)學(xué)長(zhǎng)聊天,他給我下...
    大了學(xué)那點(diǎn)事閱讀 305評(píng)論 1 1

友情鏈接更多精彩內(nèi)容