日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OAuth 2.0 的探险之旅

發(fā)布時間:2023/12/4 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OAuth 2.0 的探险之旅 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

OAuth 2.0 全稱是 Open Authorization 2.0, 是用于授權(quán)(authorization)的行業(yè)標(biāo)準(zhǔn)協(xié)議。OAuth 2.0 專注于客戶端開發(fā)人員的簡單性,同時為 Web 應(yīng)用程序、桌面應(yīng)用程序、移動設(shè)備應(yīng)用等提供了特定的授權(quán)流程。它在2012年取代了 OAuth 1.0, 并且 OAuth 2.0 協(xié)議不向后兼容 OAuth 1.0。

需要注意的是,OAuth 2.0 是一個授權(quán)(authorization)協(xié)議,而不是身份驗證(authentication )協(xié)議。

Roles 角色

首先還需要了解一些概念, 因為整個OAuth授權(quán)流程都是圍繞這些抽象的概念展開的, 角色是 OAuth2.0 授權(quán)框架核心規(guī)范的一部分, OAuth 定義了以下4種角色

?Resource Owner
資源所有者, 這里通常是擁有資源權(quán)限的用戶或者系統(tǒng)。
?Client
客戶端應(yīng)用, 它可以通過訪問令牌(Token)訪問受保護資源, 可以是Web瀏覽器上的網(wǎng)站也可以是桌面應(yīng)用或者手機App。
?Authorization Server
授權(quán)服務(wù)器, 在經(jīng)過用戶的授權(quán)后, 向客戶端應(yīng)用發(fā)放訪問令牌(Access Token)。
?Resource Server
資源服務(wù)器, 存放受保護資源的服務(wù)器, 接受來自客戶端(Client)請求的有效訪問令牌(Access Token), 然后返回對應(yīng)的資源。

Client Types 客戶端類型

OAuth 2.0 核心規(guī)范定義了兩種客戶端類型, confidential 機密的, 和 public 公開的, 區(qū)分這兩種類型的方法是, 判斷這個客戶端是否有能力維護自己的機密性憑據(jù)(password, client_secret)。

?confidential 對于一個普通的web站點來說,雖然用戶可以訪問到前端頁面, 但是數(shù)據(jù)都來自服務(wù)器的后端api服務(wù), 前端只是獲取授權(quán)碼code, 通過 code 換取access_token 這一步是在后端的api完成的, 由于是內(nèi)部的服務(wù)器, 客戶端有能力維護密碼或者密鑰信息, 這種是機密的的客戶端。
?public 對于一個沒有后端的純前端應(yīng)用來說(比如SPA), 數(shù)據(jù)的展示和操作都是在前端完成的, 包括獲取令牌和操作令牌, 把一個客戶端密碼或者密鑰放在純前端應(yīng)用是不安全的, 這種是公開的客戶端。

Client Authentication 客戶端身份認(rèn)證

前面已經(jīng)說過了, OAuth 2.0 是授權(quán)協(xié)議, 那為什么還要對 OAuth 2.0 客戶端進行身份驗證呢?身份驗證和授權(quán)有什么區(qū)別?簡單說身份驗證確認(rèn)用戶是否是本人, 而授權(quán)則是授予用戶訪問資源的權(quán)限, 授權(quán)的前提條件一定是要先通過身份認(rèn)證, 而且接下來的內(nèi)容中, 也有用到了身份認(rèn)證, 為了方便理解, 所以對認(rèn)證做了簡單的介紹。

授權(quán)服務(wù)器對客戶端進行身份驗證可以保證把令牌頒發(fā)給了合法的客戶端, 但是認(rèn)證其實已經(jīng)超出了 OAuth2.0 的協(xié)議范圍, 在 [RFC 6749] 中也只是簡單介紹了以下2種認(rèn)證方式:

第一種是使用 HTTP Basic [RFC2617] 中定義的身份驗證方案進行身份認(rèn)證, 這種方式叫 client_secret_basic, 首先需要對username,password 或者 client_id, client_secret 用冒號進行拼接。

{username}:{password}?或者?{client_id}:{client_secret}?就像這樣?admin:123456
然后對字符串進行Base64編碼, 然后設(shè)置為請求Header中的Authorization, 注意前面要拼接一個Basic和空格, 如下

POST /token HTTP/1.1Host: www.authorization-server.com Authorization: Basic YWRtaW46MTIzNDU2Content-Type: application/x-www-form-urlencoded

第二種方式就更簡單粗暴了, 直接在請求體中添加 client_id 和 client_secret 參數(shù), 如下

POST /token HTTP/1.1Host: www.authorization-server.com Content-Type: application/x-www-form-urlencodedgrant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw

Protocol Flow 協(xié)議流程

上圖是抽象的授權(quán)協(xié)議流程, 也展示了4種角色(Role)之間的交互, 具體的過程如下

(A) 客戶端向資源所有者(用戶)發(fā)起授權(quán)請求, 資源所有者選擇授予權(quán)限或者取消, 這個過程中, 授權(quán)服務(wù)器充當(dāng)中介的角色, user ---> authorization server ----> client.
(B) 客戶端收到授權(quán)許可(code),這是一個代表資源所有者授權(quán)的憑證。
(C) 客戶端通過授權(quán)許可(code)向授權(quán)服務(wù)器發(fā)起請求, 并期望獲取一個訪問令牌(access token)。
(D) 授權(quán)服務(wù)器對客戶端進行身份驗證并驗證授權(quán)許可,如果有效,則頒發(fā)訪問令牌(access token)并返回。
(E) 客戶端通過訪問令牌向資源服務(wù)器請求受保護的資源。
(F) 資源服務(wù)器驗證訪問令牌, 如果有效, 則返回相應(yīng)的資源。

Access Token 訪問令牌

access token 是一個用來訪問受保護資源的憑證, 它是由授權(quán)服務(wù)器(Authorization Server)頒發(fā)給客戶端(Client)的, 通常是字符串形式, access token 擁有特定的訪問范圍(scope), 并且有時間限制, 訪問令牌可以有不同的格式、結(jié)構(gòu), 這點并沒有限制。

Refresh Token 刷新令牌

refresh token是一個用來獲取access token的憑證, 同樣它是由授權(quán)服務(wù)器(Authorization Server)頒發(fā)給客戶端(Client)的, 刷新令牌的時效性比訪問令牌要長, 當(dāng)訪問令牌過期的時候, 可以直接用刷新令牌去授權(quán)服務(wù)器獲取新的訪問令牌, 而無需重新登錄。和訪問令牌不同的是, 授權(quán)服務(wù)器頒發(fā)訪問令牌是必須的, 而頒發(fā)刷新令牌則是可選的, 并且訪問令牌還會和資源服務(wù)器交互, 而刷新令牌只和授權(quán)服務(wù)器交互。

刷新令牌的設(shè)計非常巧妙, 它是用戶體驗和安全兩方面取舍的一個平衡。

(A) 客戶端向授權(quán)服務(wù)器發(fā)起請求, 并提供授權(quán)許可。
(B) 授權(quán)服務(wù)器對客戶端進行身份驗證并驗證授權(quán)許可,如果有效,則頒發(fā)訪問令牌和刷新令牌。
(C) 客戶端請求受保護資源并提供訪問令牌。
(D) 資源服務(wù)器驗證這個訪問令牌,如果有效, 返回相應(yīng)的內(nèi)容。
(E) 重復(fù)步驟 (C) 和 (D),直到訪問令牌過期。如果客戶端知道了訪問令牌已經(jīng)過期,它跳到步驟(G), 如果不知道, 繼續(xù)向資源服務(wù)器發(fā)起請求。
(F) 由于訪問令牌無效,資源服務(wù)器返回?zé)o效的令牌錯誤。
(G) 客戶端發(fā)起獲取刷新令牌的請求, 同時要帶上當(dāng)前的刷新令牌。
(H) 授權(quán)服務(wù)器對客戶端進行認(rèn)證并驗證刷新令牌,如果有效,則發(fā)出新的訪問令牌和一個可選的新的刷新令牌。

Authorization Grant 授權(quán)許可

授權(quán)許可是一個資源所有者授權(quán)的憑證, 客戶端通過它去獲取訪問令牌(access token), OAuth 2.0定義了以下四種許可模式。

?Authorization Code 授權(quán)碼?Implicit 隱式?Resource Owner Password Credentials 密碼?Client Credentials 客戶端憑證

Authorization Code Grant 授權(quán)碼模式

授權(quán)碼模式是最常用的一種授權(quán)許可模式, 也是最經(jīng)典的一種, 這種模式可以獲取到訪問令牌和刷新令牌。還有一個特點是, 授權(quán)碼模式是基于Web重定向的流程。

(A) 客戶端提供一個授權(quán)鏈接, 引導(dǎo)用戶點擊跳轉(zhuǎn)到授權(quán)服務(wù)的?/authorize?端點, 如下

https://www.authorization-server.com/oauth2/authorize?response_type=code&client_id=s6BhdRkqt3&scope=user&state=8b815ab1d177f5c8e &redirect_uri=https://www.client.com/callback

參數(shù)說明如下:

?response_type:必選項, 表示響應(yīng)類型,此處的值固定為"code"?client_id:必選項, 客戶端的身份標(biāo)識?redirect_uri 可選項, 經(jīng)過用戶允許授權(quán)后, 授權(quán)服務(wù)器跳轉(zhuǎn)到客戶端的回調(diào)地址?scope 可選項, 希望用戶同意授權(quán)的權(quán)限范圍?state 可選項, 推薦使用, 客戶端可以維護一個在請求和回調(diào)之間的狀態(tài), 授權(quán)服務(wù)器重定向到回調(diào)地址時, 會帶上這個參數(shù), state 可以防止跨站點請求偽造-CSRF攻擊。

(B) 授權(quán)服務(wù)器提供授權(quán)頁面, 用戶選擇同意授權(quán)或者拒絕來自客戶端的請求, 如下所示

(C) 假如用戶同意了授權(quán), 授權(quán)服務(wù)器會通過url重定向到客戶端的回調(diào)地址, 并且會帶上一個授權(quán)碼 code 和 state 參數(shù)(如果之前客戶端的請求中傳遞了state參數(shù)的話)

https://www.client.com/callback?code=d8c2afe6ecca004eb4bd7024&state=8b815ab1d177f5c8e

(D) 現(xiàn)在已經(jīng)拿到了授權(quán)碼 code 并獲得了用戶的授權(quán), 接下來需要用 code 來換取 訪問令牌 access_token, 可以向授權(quán)服務(wù)的?/token?端點發(fā)送 POST 請求。

POST /token HTTP/1.1 Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencodedhttps://www.authorization-server.com/oauth2/token?grant_type=authorization_code&code=d8c2afe6ecca004eb4bd7024&redirect_uri=https://www.client.com/callback

參數(shù)說明如下:

?grant_type: 必選項,表示授權(quán)類型, 此處的值固定為"authorization_code"
?code: 必選項,授權(quán)碼, 這是上一步從授權(quán)服務(wù)器傳給回調(diào)地址(redirect_uri)的參數(shù)
?redirect_uri: 必選項, 客戶端的回調(diào)地址, 注意要和(A)步驟中的 redirect_uri 一致。
?client_id: 必選項,客戶端的身份標(biāo)識

注意, 上面使用了 Http Basic 身份認(rèn)證(Authorization: Basic ...), 在本文的 "客戶端身份認(rèn)證" 部分有介紹, 主要是為了驗證 Client 的合法性。

通過code換取access_token 步驟中,還有一種比較常見的身份驗證做法是, 直接在請求體中傳入 client_id, client_secret, 如下:

POST /token HTTP/1.1 Content-Type: application/x-www-form-urlencodedhttps://www.authorization-server.com/oauth2/token?grant_type=authorization_code&code=d8c2afe6ecca004eb4bd7024&client_id=s6BhdRkqt3&client_secret=ecca004eb4bd7024c2afe6ecc&redirect_uri=https://www.client.com/callback

(E) 授權(quán)服務(wù)器對 client,code 驗證通過后, 會返回 access_token 和一個可選的 refresh_token, 如下:

HTTP/1.1 200 OKContent-Type: application/json;charset=UTF-8Cache-Control: no-storePragma: no-cache{ "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"bearer", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA" }

參數(shù)介紹:

?access_token: 必選項,訪問令牌
?token_type: 令牌類型, 通常是 Bearer [RFC6750], 訪問受保護資源需要在請求頭設(shè)置 (Authorization:Bearer ...)
?expires_in: 訪問令牌的有效期, 以秒為單位
?refresh_token:可選的刷新令牌

(F) 客戶端使用 access_token 向資源服務(wù)器發(fā)起請求
(G) 資源服務(wù)器驗證 access_token, 驗證通過后, 返回受保護的資源

這里有一個問題是, 文章上面說 access_token 只是一個字符串, 那么資源服務(wù)器如何來驗證該令牌?在 OAuth 2.0 核心協(xié)議中, 關(guān)于這點并沒有提及。

訪問令牌主要分為兩種, 一種是沒有意義的隨機字符串, 比如?2YotnFZFEjr1zCsicMWpAA, 這種情況客戶端本身是不能鑒別令牌是否有效, 只能去授權(quán)服務(wù)器發(fā)起請求來驗證該令牌, 這種安全性高,但性能差, 可以參考 RFC 7662.

第二種就是很常見的 JWT 令牌, 可以參考 RFC 7519, 令牌本身就包含了一些用戶信息, 資源服務(wù)器可以通過加密算法和簽名驗證令牌是否有效, 而且不需要和授權(quán)服務(wù)器進行交互, 但是缺點是, 如果令牌在到期前被撤銷, 資源服務(wù)器是沒辦法知道的。

Implicit Grant 隱式授權(quán)模式

上面是隱式授權(quán)的流程圖, 它和授權(quán)碼模式很像, 區(qū)別在于, 授權(quán)碼模式是先拿到code,然后再換取access_token, 而隱式授權(quán)只用一次請求就拿到了access_token, 通過url參數(shù)的形式返回, 令牌也直接暴露在了瀏覽器地址欄, 實際上這種模式是OAuth 2.0 對公開(public)的客戶端的授權(quán)流程進行了優(yōu)化, 上面說到了客戶端分為兩種, 機密的的和公開的, 因為公開的客戶端沒有能力維護自己的機密憑證, 所以適合這種模式, 并且授權(quán)碼模式需要客戶端認(rèn)證 (通過code換取access_token的時候,需要使用 Http Basic認(rèn)證,或者傳入client_secret) , 而隱式授權(quán)在整個流程中并沒有客戶端認(rèn)證,所以是不安全也不推薦使用的。

請求參數(shù):

response_type 這里固定是 token

GEThttps://www.authorization-server.com/oauth2/authorize?response_type=token&client_id=s6BhdRkqt3&scope=user&state=8b815ab1d177f5c8e &redirect_uri=https://www.client.com/callback

響應(yīng)參數(shù):

https://www.client.com/callback#access_token=2YotnFZFEjr1zCsicMWpAA&state=8b815ab1d177f5c8e&token_type=Bearer&expires_in=3600

這里注意 access_token 實際上并不是一個url 參數(shù), 它前面是?#?號, 表示一個fragment,?#?有別于??,??后面的查詢字符串會被網(wǎng)絡(luò)請求發(fā)送到服務(wù)器,而 fragment 則不會發(fā)送到服務(wù)器, 但是js是可以解析到fragment的值, 也就是 access_token, 這個設(shè)計很巧妙!

Resource Owner Password Credentials Grant 密碼憑證模式

密碼模式就更簡單粗暴了, 用戶直接把賬號密碼告訴客戶端, 客戶端向授權(quán)服務(wù)器發(fā)起POST請求, 并攜帶用戶名和密碼, 授權(quán)服務(wù)器驗證通過后, 返回訪問令牌和可選的刷新令牌, 這種模式的特點是, 用戶和客戶端是高度信任的。

請求參數(shù):

POST /token HTTP/1.1Host: www.authorization-server.comAuthorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencodedgrant_type=password&username=johndoe&password=A3ddj3w

響應(yīng)參數(shù):

HTTP/1.1 200 OKContent-Type: application/json;charset=UTF-8Cache-Control: no-storePragma: no-cache{ "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"Bearer", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA" }

Client Credentials Grant 客戶端憑證模式

客戶端憑證模式的特點是, 客戶端就是資源所有者, 客戶端訪問資源也不需要用戶的授權(quán), 因為這個過程中沒有用戶, 資源本身就屬于客戶端, 通過在請求體中傳入 client_id,client_secret參數(shù)或者Http Basic 進行客戶端認(rèn)證, 這種模式很適合后端服務(wù)或者api之間調(diào)用的場景。

請求參數(shù):

此處的 grant_type 固定是 client_credentials

POST /token HTTP/1.1Host: www.authorization-server.comAuthorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencodedgrant_type=client_credentials

響應(yīng)參數(shù):

HTTP/1.1 200 OKContent-Type: application/json;charset=UTF-8Cache-Control: no-storePragma: no-cache{ "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"Bearer", "expires_in":3600, "example_parameter":"example_value"}

總結(jié)

本文介紹了 OAuth 2.0 核心協(xié)議, 主要參考 RFC 6749 (The OAuth 2.0 Authorization Framework) 核心協(xié)議 , 相信讀完本文, 你會發(fā)現(xiàn)有些流程其實是不安全的, 沒錯, 其中的隱式授權(quán)和密碼授權(quán)模式已經(jīng)不再建議使用, 因為隱式授權(quán)從一開始就沒有真正安全過, 這里介紹一下背景, 當(dāng)時 OAuth 2.0 出現(xiàn)的時間點在2010年左右, 移動端應(yīng)用是全新的,單頁面應(yīng)用程序(SPA) 也才剛開始出現(xiàn), 當(dāng)時的Web生態(tài)和現(xiàn)在還是差別很大, 由于技術(shù)問題, 并不能使用常規(guī)的 OAuth 模式進行授權(quán)。對于現(xiàn)在來說, 推薦使用專門為移動設(shè)備應(yīng)用而設(shè)計的 PKCE (RFC 7636) 模式, 它是OAuth 2.0 核心的一個擴展協(xié)議, 也是最近幾年移動設(shè)備應(yīng)用授權(quán)的最佳實踐。

目前 OAuth 2.1 也是一項正在進行中的工作, 它圍繞 OAuth 2.0 對其授權(quán)功能進行加強和優(yōu)化, 下篇文章我會繼續(xù)介紹 OAuth 2.1 的新功能。

References

?https://www.rfc-editor.org/rfc/rfc6749?https://www.rfc-editor.org/rfc/rfc6750?https://www.rfc-editor.org/rfc/rfc7662?https://www.rfc-editor.org/rfc/rfc5849?https://www.rfc-editor.org/rfc/rfc2617?https://www.rfc-editor.org/rfc/rfc7519?https://oauth.net/2/?https://www.youtube.com/watch?v=CHzERullHe8?https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-13#section-3.4

😃 歡迎關(guān)注微信公眾號【全球技術(shù)精選】


總結(jié)

以上是生活随笔為你收集整理的OAuth 2.0 的探险之旅的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。