OAuth 2 深入介紹

来源:https://www.cnblogs.com/Wddpct/archive/2018/05/01/8976480.html
-Advertisement-
Play Games

更友好的閱讀體驗,請轉至 OAuth 深入介紹 。 1. 前言 2. OAuth2 角色 2.1 資源所有者(Resource Owner) 2.2 資源/授權伺服器(Resource/Authorization Server) 2.3 客戶端(Client) 3. OAuth 2 的授權流程 4. ...


更友好的閱讀體驗,請轉至 OAuth 深入介紹

1. 前言

OAuth 2 是一個授權框架,或稱授權標準,它可以使第三方應用程式或客戶端獲得對HTTP服務上(例如 Google,GitHub )用戶帳戶信息的有限訪問許可權。OAuth 2 通過將用戶身份驗證委派給托管用戶帳戶的服務以及授權客戶端訪問用戶帳戶進行工作。綜上,OAuth 2 可以為 Web 應用 和桌面應用以及移動應用提供授權流程。

本文將從OAuth 2 角色,授權許可類型,授權流程等幾方面進行講解。

在正式講解之前,這裡先引入一段應用場景,用以與後文的角色講解對應。

開發者A註冊某IT論壇後,發現可以在信息欄中填寫自己的 Github 個人信息和倉庫項目,但是他又覺得手工填寫十分麻煩,直接提供 Github 賬戶和密碼給論壇管理員幫忙處理更是十分智障。
不過該論壇似乎和 Github 有不可告人的秘密,開發者A可以點擊“導入”按鈕,授權該論壇訪問自己的 Github 賬戶並限制其只具備讀許可權。這樣一來, Github 中的所有倉庫和相關信息就可以很方便地被導入到信息欄中,賬戶隱私信息也不會泄露。
這背後,便是 OAuth 2 在大顯神威。

2. OAuth2 角色

OAuth 2 標準中定義了以下幾種角色:

  • 資源所有者(Resource Owner)
  • 資源伺服器(Resource Server)
  • 授權伺服器(Authorization Server)
  • 客戶端(Client)

2.1 資源所有者(Resource Owner)

資源所有者是 OAuth 2 四大基本角色之一,在 OAuth 2 標準中,資源所有者即代表授權客戶端訪問本身資源信息的用戶(User),也就是應用場景中的“開發者A”。客戶端訪問用戶帳戶的許可權僅限於用戶授權的“範圍”(aka. scope,例如讀取或寫入許可權)。

如果沒有特別說明,下文中出現的"用戶"將統一代表資源所有者。

2.2 資源/授權伺服器(Resource/Authorization Server)

資源伺服器托管了受保護的用戶賬號信息,而授權伺服器驗證用戶身份然後為客戶端派發資源訪問令牌。

在上述應用場景中,Github 既是授權伺服器也是資源伺服器,個人信息和倉庫信息即為資源(Resource)。而在實際工程中,不同的伺服器應用往往獨立部署,協同保護用戶賬戶信息資源。

2.3 客戶端(Client)

在 OAuth 2 中,客戶端即代表意圖訪問受限資源的第三方應用。在訪問實現之前,它必須先經過用戶者授權,並且獲得的授權憑證將進一步由授權伺服器進行驗證。

如果沒有特別說明,下文中將不對"應用",“第三方應用”,“客戶端”做出區分。

3. OAuth 2 的授權流程

目前為止你應該對 OAuth 2 的角色有了些概念,接下來讓我們來看看這幾個角色之間的抽象授權流程圖和相關解釋。

請註意,實際的授權流程圖會因為用戶返回授權許可類型的不同而不同。但是下圖大體上能反映一次完整抽象的授權流程。

  1. Authrization Request
    客戶端向用戶請求對資源伺服器的authorization grant
  2. Authorization Grant(Get)
    如果用戶授權該次請求,客戶端將收到一個authorization grant
  3. Authorization Grant(Post)
    客戶端向授權伺服器發送它自己的客戶端身份標識和上一步中的authorization grant,請求訪問令牌。
  4. Access Token(Get)
    如果客戶端身份被認證,並且authorization grant也被驗證通過,授權伺服器將為客戶端派發access token。授權階段至此全部結束。
  5. Access Token(Post && Validate)
    客戶端向資源伺服器發送access token用於驗證並請求資源信息。
  6. Protected Resource(Get)
    如果access token驗證通過,資源伺服器將向客戶端返回資源信息。

4. 客戶端應用註冊

在應用 OAuth 2 之前,你必須在授權方服務中註冊你的應用。如 Google Identity Platform 或者 Github OAuth Setting,諸如此類 OAuth 實現平臺中一般都要求開發者提供如下所示的授權設置項。

  • 應用名稱
  • 應用網站
  • 重定向URI或回調URL

重定向URI是授權方服務在用戶授權(或拒絕)應用程式之後重定向供用戶訪問的地址,因此也是用於處理授權碼或訪問令牌的應用程式的一部分。

4.1 Client ID 和 Client Secret

一旦你的應用註冊成功,授權方服務將以client idclient secret的形式為應用發佈client credentials(客戶端憑證)。client id是公開透明的字元串,授權方服務使用該字元串來標識應用程式,並且還用於構建呈現給用戶的授權 url 。當應用請求訪問用戶的帳戶時,client secret用於驗證應用身份,並且必須在客戶端和服務之間保持私有性。

5. 授權許可(Authorization Grant)

如上文的抽象授權流程圖所示,前四個階段包含了獲取authorization grantaccess token的動作。授權許可類型取決於應用請求授權的方式和授權方服務支持的 Grant Type。OAuth 2 定義了四種 Grant Type,每一種都有適用的應用場景。

  • Authorization Code
    結合普通伺服器端應用使用。
  • Implicit
    結合移動應用或 Web App 使用。
  • Resource Owner Password Credentials
    適用於受信任客戶端應用,例如同個組織的內部或外部應用。
  • Client Credentials
    適用於客戶端調用主服務API型應用(比如百度API Store)

以下將分別介紹這四種許可類型的相關授權流程。

5.1 Authorization Code Flow

Authorization Code 是最常使用的一種授權許可類型,它適用於第三方應用類型為server-side型應用的場景。Authorization Code授權流程基於重定向跳轉,客戶端必須能夠與User-agent(即用戶的 Web 瀏覽器)交互並接收通過User-agent路由發送的實際authorization code值。

1. User Authorization Request

首先,客戶端構造了一個用於請求authorization code的URL並引導User-agent跳轉訪問。

https://authorization-server.com/auth
 ?response_type=code
 &client_id=29352915982374239857
 &redirect_uri=https%3A%2F%2Fexample-client.com%2Fcallback
 &scope=create+delete
 &state=xcoiv98y2kd22vusuye3kch
  • response_type=code
    此參數和參數值用於提示授權伺服器當前客戶端正在進行Authorization Code授權流程。
  • client_id
    客戶端身份標識。
  • redirect_uri
    標識授權伺服器接收客戶端請求後返回給User-agent的跳轉訪問地址。
  • scope
    指定客戶端請求的訪問級別。
  • state
    由客戶端生成的隨機字元串,步驟2中用戶進行授權客戶端的請求時也會攜帶此字元串用於比較,這是為了防止CSRF攻擊。

2. User Authorizes Applcation

當用戶點擊上文中的示例鏈接時,用戶必須已經在授權服務中進行登錄(否則將會跳轉到登錄界面,不過 OAuth 2 並不關心認證過程),然後授權服務會提示用戶授權或拒絕應用程式訪問其帳戶。以下是授權應用程式的示例:

3. Authorization Code Grant

如果用戶確認授權,授權伺服器將重定向User-agent至之前客戶端提供的指向客戶端的redirect_uri地址,並附帶codestate參數(由之前客戶端提供),於是客戶端便能直接讀取到authorization code值。

https://example-client.com/redirect
 ?code=g0ZGZmNjVmOWIjNTk2NTk4ZTYyZGI3
 &state=xcoiv98y2kd22vusuye3kch

state值將與客戶端在請求中最初設置的值相同。客戶端將檢查重定向中的狀態值是否與最初設置的狀態值相匹配。這可以防止CSRF和其他相關攻擊。

code是授權伺服器生成的authorization code值。code相對較短,通常持續1到10分鐘,具體取決於授權伺服器設置。

4. Access Token Request

現在客戶端已經擁有了伺服器派發的authorization code,接下來便可以使用authorization code和其他參數向伺服器請求access token(POST方式)。其他相關參數如下:

  • grant_type=authorization_code - 這告訴伺服器當前客戶端正在使用Authorization Code授權流程。
  • code - 應用程式包含它在重定向中給出的授權碼。
  • redirect_uri - 與請求authorization code時使用的redirect_uri相同。某些資源(API)不需要此參數。
  • client_id - 客戶端標識。
  • client_secret - 應用程式的客戶端密鑰。這確保了獲取access token的請求只能從客戶端發出,而不能從可能截獲authorization code的攻擊者發出。

5. Access Token Grant

伺服器將會驗證第4步中的請求參數,當驗證通過後(校驗authorization code是否過期,client idclient secret是否匹配等),伺服器將向客戶端返回access token

{
  "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
  "token_type":"bearer",
  "expires_in":3600,
  "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk",
  "scope":"create delete"
}

至此,授權流程全部結束。直到access token 過期或失效之前,客戶端可以通過資源伺服器API訪問用戶的帳戶,並具備scope中給定的操作許可權。

5.2 Implicit Flow

Implicit授權流程和Authorization Code基於重定向跳轉的授權流程十分相似,但它適用於移動應用和 Web App,這些應用與普通伺服器端應用相比有個特點,即client secret不能有效保存和信任。

相比Authorization Code授權流程,Implicit去除了請求和獲得authorization code的過程,而用戶點擊授權後,授權伺服器也會直接把access token放在redirect_uri中發送給User-agent(瀏覽器)。 同時第1步構造請求用戶授權 url 中的response_type參數值也由 code 更改為 tokenid_token

1. User Authorization Request

客戶端構造的URL如下所示:

https://{yourOktaDomain}.com/oauth2/default/v1/authorize?client_id=0oabv6kx4qq6
h1U5l0h7&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3
A8080&state=state-296bc9a0-a2a2-4a57-be1a-d0e2fd9bb601&nonce=foo'

response_typeresponse_type參數值為 tokenid_token 。其他請求參數與Authorization Code授權流程相比沒有並什麼變化。

2. User Authorizes Application(略)

3. Redirect URI With Access Token In Fragment

假設用戶授予訪問許可權,授權伺服器將User-agent(瀏覽器) 重定向回客戶端使用之前提供的redirect_uri。併在 uri 的 #fragment 部分添加access_token鍵值對。如下所示:

http://localhost:8080/#access_token=eyJhb[...]erw&token_type=Bearer&expires_in=3600&scope=openid&state=state-296bc9a0-a2a2-4a57-be1a-d0e2fd9bb601
  • token_type - 當且僅當response_type設置為 token 時返回,值恆為 Bearer

註意在Implicit流程中,access_token值放在了 URI 的 #fragment 部分,而不是作為 ?query 參數。

4. User-agent Follows the Redirect URI

User-agent(瀏覽器)遵循重定向指令,請求redirect_uri標識的客戶端地址,併在本地保留 uri 的 #fragment 部分的access_token信息

5. Application Sends Access Token Extraction Script

客戶端生成一個包含 token 解構腳本的 Html 頁面,這個頁面被髮送給User-agent(瀏覽器),執行腳本解構完整的redirect_uri並提取其中的access_tokenaccess token信息在第4步中已經被User-agent保存)。

6. Access Token Passed to Application

User-agent(瀏覽器)向客戶端發送解構提取的access token

至此,授權流程全部結束。直到access token 過期或失效之前,客戶端可以通過資源伺服器API訪問用戶的帳戶,並具備scope中給定的操作許可權。

5.3 Resource Owner Password Credentials Flow

Resource Owner Password Credentials授權流程適用於用戶與客戶端具有信任關係的情況,例如設備操作系統或同一組織的內部及外部應用。用戶與應用交互表現形式往往體現為客戶端能夠直接獲取用戶憑據(用戶名和密碼,通常使用交互表單)。

1. Resource Owner Password Credentials From User Input

用戶向客戶端提供用戶名與密碼作為授權憑據。

2. Resource Owner Password Credentials From Client To Server

客戶端向授權伺服器發送用戶輸入的授權憑據以請求 access token。客戶端必須已經在伺服器端進行註冊。

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
  • grant_type - 必選項,值恆為 password

3. Access Token Passed to Application

授權伺服器對客戶端進行認證並檢驗用戶憑據的合法性,如果檢驗通過,將向客戶端派發 access token>

{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter":"example_value"
}

5.4 Client Credentials Flow

Client Credential是最簡單的一種授權流程。客戶端可以直接使用它的client credentials或其他有效認證信息向授權伺服器發起獲取access token的請求。

兩步中的請求體和返回體分別如下:

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

grant_type=client_credentials
  • grant_type - 必選項,值恆為 client_credentials
{
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "example_parameter":"example_value"
}

6. 總結

說實在的,筆者已經有很長一段時間沒有好好地分享心得,發表博客,這固然有工作繁忙,學習充實的原因,但確實也是有些懶,既然認識到了,自然就不希望再墮落下去了。

這一年裡讀了很多書,做了很多事,雖然自覺在大學時期便接觸了部分項目管理和開發的知識,但是工作後的收穫仍然十分動心。微服務也好,DDD也好,或是具體的資料庫理論和運維工程實踐上筆者也有了更深的認識。而時至今日,筆者覺得自己是又到了重新積澱,重新邁向下一個階段的時候。鑒權服務作為構建健壯微服務必不可少的一環(甚至可以說是第一個工程),所以以 OAuth 2 作為重啟的第一篇。當然 OAuth 2 也仍然只是鑒權體系中的授權理論,更基礎的認證(Authentication)理論還沒有引出,希望在之後的日子里能帶來更多關於鑒權相關的博文,如認證體系和功能許可權設計在工程上的應用,共勉。

學習和編程都是快樂的。

參考資料及文獻

  1. The OAuth 2.0 Authorization Framework
  2. What is the OAuth 2.0 Authorization Code Grant Type?
  3. An Introduction to OAuth 2
  4. Implicit Flow
  5. Response Properties
  6. 認證授權 OAuth2授權

名詞中英文對照

英文 中文
Authorization Grant 授權許可
Authorization Code 授權碼
Access Token 訪問令牌
Authorization 授權
Authentication 認證

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 三維變換使用基於二維變換的相同屬性。3D變換功能與2D變換功能相當類似,css3中3D變換主要有4個功能函數: 1、3D位移:CSS3中的3D位移主要包括translateZ()和translate3d()兩個功能函數。 2、3D旋轉:CSS3中的3D旋轉主要包括rotateX(),rotateY( ...
  • 一、JS的變數 1.變數的聲明 2.使用一行代碼強調多個語句。其中b為undefined; 3.JS中變數聲明的註意事項。 ①JS中聲明變數的關鍵字只有var一個,變數的類型取決於所附的值。 如果聲明時未賦值,則返回undefined類型(聲明之後沒有賦值的變數,不是未聲明)。②JS中同一個變數,可 ...
  • 元素(element) 類型:替換和非替換元素 替換元素(replaced element): 用來替換元素內容的部分並非由文檔內容直接顯示. eg:img input 非替換元素(nonreplaced element): 其內容由用戶代理在元素本身生成的框顯示. eg:絕大多數都是非替換元素 基 ...
  • 前端技術之_CSS詳解第一天 一html部分 略。。。。 二、列表 列表有3種 2.1 無序列表 無序列表,用來表示一個列表的語義,並且每個項目和每個項目之間,是不分先後的。 ul就是英語unordered list,“無序列表”的意思。 li 就是英語list item , “列表項”的意思。 你 ...
  • transform轉換屬性的5個值: 1、 translate(x值,y值) 移動效果。 2、rotate(45deg) 旋轉效果。 3、scale(x軸倍數,y軸倍數) 縮放效果。 4、skew(x軸deg,y軸deg) 傾斜效果。 5、matrix() 矩陣 ...
  • 面向對象第八次作業 代碼分析 第五次作業 多線程電梯 UML圖和協作圖 代碼複雜度分析 這次作業的主要難點在於對於多線程的理解和實踐,一方面由於老師上課講的著急,內容也更多的偏向JVM的介紹,因此對於多線程編程的一些思路和方法沒有多少瞭解,另一方面由於時間不足也沒有時間去更詳細的自學多線程,因此基本 ...
  • 前言 在最近一個月的面向對象編程學習中,我們進入了編寫多線程程式的階段。線程的創建、調度和信息傳遞,共用對象的處理,線程安全類的編寫,各種有關於線程的操作在一定程度上增加了近三次作業的複雜度與難度,帶來了不小的考驗。本文通過分析總結近三次作業的完成情況,分享我對與多線程編程的一些見解與體會。 作業總 ...
  • 今天5月1號了,回鄭州,在家待了三天。打了幾天手游,花了不少錢。家裡準備再蓋座房子,我也應該為家裡做些貢獻。真他娘累,30多了,單身,現在已有些恐婚了。近期有空要做個記賬軟體,否則錢花的太快了。這個月,20多號還要軟考,我這應該是考不過了,基本放棄了。老闆原說漲3K,又變成2K,坑,套路。 近期我寫 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...