`

[转]OAuth 2.0 筆記 (4.2) Implicit Grant Flow 細節

阅读更多

OAuth 2.0 筆記 (4.2) Implicit Grant Flow 細節

在 Implicit Grant Flow 裡,Authorization Server 直接向 Client 核發 Access Token ,而不像 Authorization Code Grant Flow ,先核發 Grant ,再另外去拿 Access Token。

Authorization Server 核發 Access Token 的時候,不認證 Client (其實也無法認證),在某些情況下,可以用 Redirection URI 來確保 Access Token 只發給正確的 Client 。這種流程依賴 Resource Owner 本人的存在,以及事先設定的 Redirection URI。

這種流程是專門為特定的 Public Client 來優化的,例如跑在 Browser 裡面的應用程式。但也因此有外洩風險,例如:

  • Resource Owner 可以看到 Access Token
  • 其他可以存取 User-Agent 的應用程式,也可以看到 Access Token
  • Access Token 傳輸時,會直接出現在 Redirection URI 裡面,所以 Resource Owner 以及同一台設備的應用程式可以看到

因為需要實施轉址,所以 Client 要可以跟 Resource Owner 的 User-Agent (Browser) 互動,也要可以接收從 Authorization Server 來的 Redirection Request。(同 Authorization Code Grant Flow)

最後拿到的只有 Access Token ,不會拿到 Refresh Token (禁止核發 Refresh Token)。

這是 OAuth 2.0 內建的四個流程之一。本文整理自 Section 4.2。

流程圖

+----------+
| 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 |
|         |
+---------+

註: (A), (B) 這兩步的線拆成兩段,因為會經過 user-agent

                    Figure 4: Implicit Grant Flow

(A) Client 把 Resource Owner 的 User-Agent 轉到 Authorization Endpoint 來啟動流程。Client 會傳送:

  • Client ID
  • 申請的 scopes
  • 內部 state
  • Redirection URI,申請結果下來之後 Authorization Server 要轉址過去。

(B) Authorization Server 通過 User-Agent 認證 Resource Owner,並確定 Resource Onwer 許可或駁回Client 的存取申請。

(C) 假設 Resource Owner 許可了存取申請, Authorization Server 會把 User-Agent 轉回去先前指定的 Redirection URI ,其中包含 Access Token ,放在 Fragment Component 裡面。

(D) User-Agent 跟隨轉址的指示,發出 Request 到 Web-Hosted Client Resource ,這個 Request 裡面不會有剛剛拿到的 Fragment , User-Agent 自己保留 Fragment 。(註)

(E) Web-Hosted Client Resource 回傳一個網頁(HTML & JavaScript),這個網頁可以拿到完整的 Redirection URI (含先前 User-Agent 保留的 Fragment)、把 Fragment 裡面的 Access Token 和其他參數給解出來。(註)

(F) User-Agent 執行從 Web-Hosted Client Resource 來的 Script 把 Access Token 解出來。

(G) User-Agent 把 Access Token 傳給 Client。

註: (D) 之後的有點抽象,我的理解是這樣:

  • Web-Hosted Client Resource 當作你自己架的 App Server ,在上面開 Redirection Endpoint ,所以這個流程其實 Client 本體 (JavaScript App) 沒有 Endpoint ,Endpoint 是開在一個 HTTP(s) Server 上面。
  • Browser 事實上在 Access http://example.com/cb#access_token=123 的時候,只會發送http://example.com/cb 的 request ,在 Request 裡面不會有 #access_token=123
  • 所以 (D) 所謂「Request 不含 Fragment,User-Agent 自己保留 Fragment」這一步是 User-Agent 自動做的, Client 開發者不需要用 JavaScript 特別處理,只要把 Redirection Endpoint 指定給自己的 App Server 就可以了。
  • 而 (E) 所謂「回傳一個網頁來解出 User-Agent 保留的 Fragment」,就是說 User-Agent 打 Request 到 Redirection URI (含 Fragment,但不會傳送到 Server)的時候,他的 response 裡面包含 JavaScript ,而上面說了,Fragment 是自動保留在 User-Agent 的,所以這個 Response 在 Server 那邊不會知道有 Fragment 的存在,也就不會知道 Access Token 的存在,而是 User-Agent 才知道。
  • 所以 (F) 就是跑這個 script 解出 Access Token 和參數,(G) 把 (F) 的執行結果塞給 Client (JavaScript App)。

也就是說其實是設計給不能聽 Redirection Endpoint 的 In-Browser JavaScript App 的解法。我看到的用法是 Google 的 OAuth 2.0 for Client-side JavaScript

(A) Authorization Request

【User-Agent】GET ▶【Authorization Endpoint】

第一步是 Client 產生一個 URL 連到 Authorization Endpoint ,要 Resource Owner 打開(點擊)這個 URL ,從而產生「向 Authorization Endpoint 發送 GET request」的操作。

把參數包在 URI 的 query component 裡面。

參數

參數名 必/選 填什麼/意義
response_type token
client_id 自己的 Client ID
state 建議有 內部狀態
redirect_uri 申請結果下來之後要轉址去哪裡
scope 申請的存取範圍

其中的 state, Authorization Server 轉回 Client 的時候會附上。可以防範 CSRF ,所以最好是加上這個值,詳見系列文第 7 篇關於 CSRF 的安全性問題。

Authorization Server 的處理程序

因為 Implicit Grant Flow 是直接在 Authorization Endpoint 發 Access Token ,所以資料驗證和授權都在這一步處理。所以這個 Request 進來的時候, Authorization Server 要做這些事:

  1. 驗證所有必須給的參數都有給且合法
    • Redirection URI 與預先在 Authorization Server 設定的相符。

如果沒問題,就詢問 Resource Owner 是否授權,即 (B) 步驟。

(C) Authorization Response

【Client】 ◀ 302【Authorization Endpoint】

是 Resource Owner 在 (B) 決定授權與否之後回應的 Response。

在 (B) 裡面, Resource Owner 若同意授權,這個「同意授權」的 request 會往 Authorization Endpoint 發送,接著會收到 302 的轉址 response ,裡面帶有「前往 Client 的 Redirection Endpoint 的 URL」的轉址 (Location header),從而產生「向 Redirection URI 發送 GET Request」的操作。

參數要用 URL Encoding 編起來,放在 Fragment Component 裡面。

若 Access Token Request 合法且有經過授權,則核發 Access Token。如果 Client 認證失敗,或 Request 不合法,則依照 Section 5.2 的規定回覆錯誤。

特別注意 Implicit Grant Type 禁止 核發 Refresh Token。

某些 User-Agent 不支援 Fragment Redirection ,這種情況可以使用間接轉址,即是轉到一個頁面,放一個 “Continue” 的按鈕,按下去連到真正的 Redirection URI 。

參數

參數名 必/選 填什麼/意義
access_token 即 Access Token
expires_in 建議有 幾秒過期,如 3600 表示 10 分鐘。若要省略,最好在文件裡註明效期。
scope 必* Access Token 的授權範圍 (scopes)。
state 必* 原內部狀態。

其中 scope 如果和 (A) 申請的不同則要附上,如果一樣的話就不必附上。

其中 state 如果 (A) 的時候有附上,則 Resopnse 裡面必須有,完全一致的原值。如果原本就沒有,就不需要回傳。

Access Token 的長度由 Authorization Server 定義,應寫在文件中, Client 不可以瞎猜。

Client 遇到不認識的參數必須忽略。

範例

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

錯誤發生時的處理方式

跟 Authorization Code Grant Flow 相同,差別在於錯誤的內容是放在 Fragment Component 而不是 Query Component。請參考系列文第 4.1 篇關於 Authorization Code Grant Flow 的 Access Token Request 錯誤處理原則。

例如:

HTTP/1.1 302 Found
Location: https://client.example.com/cb#error=access_denied&state=xyz

安全性問題

在 spec 裡面提及的安全性問題寫在 Section 10.3 和 10.16 ,其中 10.3 只是特別提到 Implicit Grant Type 「透過 URI Fragment 來傳 Access Token ,所以可能會外洩」,而 10.16 則是針對 Implicit Grant Type 可能會有偽造 Resource Owner 的安全性問題。其中 10.3 關於 Access Token 保密的問題,見系列文第 7 篇

誤用 Access Token 來在 Implicit Flow 裡面偽裝 Resource Owner (Section 10.16)

這個 Section 的原文我看不太懂,似乎是在說,這流程裡面會有漏洞讓壞人可以置換 Access Token ,原本是要給 A Client 的 Token 到了 B Client 的手上。Amazon 的文件 裡面有提到,他的建議是,在真的拿 Token 來用之前,要去 Authorization Server 問一下是不是真是給這個 Client 用的,不是的話就不能用。

新浪微博 API 的「用户身份伪造」應該也是在講類似的事

 

转自:https://blog.yorkxin.org/2013/09/30/oauth2-4-2-implicit-grant-flow

分享到:
评论

相关推荐

    Spring Security OAuth2.0学习笔记.zip

    Spring Security OAuth2.0学习笔记 什么是认证、授权、会话。 Java Servlet为支持http会话做了哪些事儿。 基于session认证机制的运作流程。 基于token认证机制的运作流程。 理解Spring Security的工作原理,Spring ...

    完整Oauth 2.0实现实例

    OAuth 2.0 是一种广泛使用的授权框架,它允许第三方应用在用户许可的情况下访问其私有资源。在本文中,我们将深入探讨 OAuth 2.0 的核心概念,并结合 Java 实现来理解其工作原理。 OAuth 2.0 主要分为四个角色:...

    cas3.5.0集成oauth2.0协议

    **OAuth2.0协议概述** OAuth2.0是一种授权框架,允许第三方应用在用户许可的情况下,访问特定资源。它主要用于安全地实现用户数据的共享,比如社交媒体登录、云存储服务等。OAuth2.0的核心是将用户的授权过程与实际...

    微信oauth2.0授权

    微信OAuth2.0授权是一种广泛应用于移动应用和网站的第三方登录解决方案,主要目的是为了安全地获取用户的微信身份标识——openid,以便提供个性化服务或者与其他微信功能集成。在本文中,我们将详细探讨微信OAuth2.0...

    webapi基于Owin中间件的oauth2.0身份认证

    **OAuth2.0简介** OAuth2.0是一种授权框架,广泛应用于Web API的身份验证和授权。它允许第三方应用在用户授权的情况下,访问该用户的特定资源,而无需获取用户的用户名和密码。OAuth2.0的核心是将认证和授权分离,...

    基于Django2.1.2的OAuth2.0授权登录

    **基于Django 2.1.2的OAuth2.0授权登录详解** OAuth2.0是一种开放标准,用于授权第三方应用访问用户存储在另一服务提供商(如社交媒体网站)上的私有资源,而无需共享用户的登录凭证。在Django框架中实现OAuth2.0...

    Oauth2.0 协议 服务端 客户端 thinkphp5.0

    在本项目中,我们将探讨如何将OAuth2.0整合到PHP框架ThinkPHP5.0中,实现服务端和客户端的授权码模式(Authorization Code Grant)。 首先,OAuth2.0协议主要包括四个角色:资源所有者(Resource Owner)、客户端...

    OAuth2.0协议原理与实现

    ### OAuth2.0协议原理与实现 #### 一、OAuth2.0协议概述 OAuth2.0协议是一种广泛应用于第三方登录及授权的标准协议。相比于OAuth1.0版本,OAuth2.0进行了多方面的优化和改进,例如简化了授权流程、取消了Token的...

    OAuth2.0协议中文版.pdf

    OAuth2.0是OAuth协议的延续版本,但不向前兼容OAuth 1.0(即完全废止了OAuth1.0)。 OAuth 2.0关注客户端开发者的简易性。要么通过组织在资源拥有者和HTTP服务商之间的被批准的交互动作代表用户,要么允许第三方应用...

    java实现oauth2.0服务端+客户端(含JWT)

    OAuth 2.0 是一个授权框架,用于安全地允许第三方应用访问用户存储在另一服务上的资源,而无需共享用户凭证。在这个Java实现中,我们利用了MAVEN作为项目管理工具和OLTU库来构建OAuth 2.0服务端和客户端。同时,数据...

    springboot集成oauth2.0

    SpringBoot集成OAuth2.0是将流行的OAuth2.0安全框架与SpringBoot应用程序相结合的过程,以便为API和Web应用提供安全的访问控制。OAuth2.0是一个授权框架,允许第三方应用在用户授权的情况下访问其受保护的资源,而...

    Jwt.zip_jwt_oauth2.0_oauth2.0 加解密_php解密工具

    这个工具可能还支持 OAuth 2.0 的相关功能,如生成和验证 OAuth 2.0 授权令牌。在使用这个工具之前,需要理解 JWT 和 OAuth 2.0 的基本原理,并按照库的文档或说明进行配置和调用。 总的来说,JWT 和 OAuth 2.0 是...

    OAuth2.0最简向导.pdf

    课程讲义所提及的视频资源和文章可以作为学习OAuth 2.0的入门材料,帮助开发者从基础开始深入理解并运用OAuth 2.0授权框架。通过这些材料,开发者可以学习如何为应用程序实现授权流程,以及如何正确使用AccessToken...

    OAuth2.0授权系统实现单点登录

    OAuth2.0的核心概念包括四个主要角色:资源所有者(Resource Owner)、客户端(Client)、授权服务器(Authorization Server)和资源服务器(Resource Server)。资源所有者是拥有数据的用户,客户端是需要访问这些...

    OAuth2.0 使用到的jar包

    OAuth2.0是一种广泛应用于各种在线服务的授权框架,它允许第三方应用安全地访问用户的受保护资源,而无需用户直接共享他们的登录凭证。在Java环境中实现OAuth2.0,通常会依赖于一些特定的jar包。这些jar包包含了处理...

    Java的oauth2.0 服务端与客户端的实现 (完整源码、demo)

    Java的oauth2.0 服务端与客户端的实现.zip 封装了oauth2.0的基本架构和实现,对照我的博客http://blog.csdn.net/jing12062011/article/details/78147306使用该源码。 下载项目压缩包,解压,里面两个maven项目:...

    OAuth 2.0 (Getting started with OAuth2.0)

    OAuth 2.0 是一种广泛使用的开放标准,用于授权第三方应用程序访问用户在特定服务上的数据,而无需共享用户的登录凭证。这个协议的核心在于提供了一种安全的机制,使得用户可以控制哪些应用能访问他们的资源,比如...

    springboot OAuth2.0-demo

    **OAuth2.0简介** OAuth2.0 是一个授权框架,允许第三方应用在用户许可的情况下,访问其存储在另一服务提供者上的特定信息。这个框架主要用于保护用户数据,避免将用户的用户名和密码直接暴露给第三方应用,提高了...

Global site tag (gtag.js) - Google Analytics