1. 程式人生 > >[認證授權] 2.OAuth2授權(續) & JWT(JSON Web Token)

[認證授權] 2.OAuth2授權(續) & JWT(JSON Web Token)

1 RFC6749還有哪些可以完善的?

1.1 撤銷Token

在上篇[認證授權] 1.OAuth2授權 中介紹到了OAuth2可以幫我們解決第三方Client訪問受保護資源的問題,但是隻提供瞭如何獲得access_token,並未說明怎麼來撤銷一個access_token。關於這部分OAuth2單獨定義了一個RFC7009 - OAuth 2.0 Token Revocation來解決撤銷Token問題。

1.2 Token對Client的不透明問題

OAuth2提供的“access_token"是一個對Client不透明的字串,儘管有"scope","expires_in"和"refresh_token

"來輔助,但也是不完善的且分散的資訊。還拿上一篇的小明來舉例,“小明授權線上列印並且包郵的網站訪問自己的QQ空間相簿”。雙引號裡面的這句話其中有4個重要的概念:

  1. 授權者小明:表示是小明授權,而不是隔壁老王。
  2. 被授權者線上列印並且包郵的網站:表示授權給指定的網站,而不是其他的比如1024.com之類的網站(你懂的。。。)。
  3. 小明自己的QQ空間:表示讓被授權者訪問自己的資訊,而不是隔壁老王的資訊,小明也沒這許可權來著,不然隔壁王嬸夜不答應吧。。。
  4. 相簿:表示你可以訪問我的相簿,而不是我的日誌,我的其他資訊。

那麼如何得到獲得上面提到的這些附加的資訊呢?OAuth2又單獨提供了一個

RFC7662 -OAuth 2.0 Token Introspection來解決Token的描述資訊不完整的問題。

這些資訊不但對Client不透明,對於資源伺服器來說也是不透明的,比如授權伺服器和資源伺服器是獨立部署的,而OAuth2又要求資源伺服器要對access token做校驗,沒有這些資訊如何校驗呢?除非在access token的db儲存層面做共享,但是作為一個執行在網際網路規模上的網路環境下的協議,這種假設是無法支撐網際網路規模的環境的。

2 OAuth2 Token 撤銷(RFC7009 - OAuth2 Token Revocation)

簡單來說,這個協議規定了一個Authorization server提供一個怎樣的API來供Client撤銷access_token或者refresh_token。

比如Client發起一個如下的請求:

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

token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token

其中各項含義如下:

  1. /revoke:是Authorization Server需要提供的API地址,Client使用Post方式請求這個地址。
  2. Content-Type: application/x-www-form-urlencoded:固定此格式。
  3. Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW:訪問受保護資源的授權憑證。
  4. token:必選,可以是access_token或者refresh_token的內容。
  5. token_type_hint:可選,表示token的型別,值為”access_token“或者"refresh_token"。

如果撤銷成功,則返回一個HTTP status code為200的響應就可以了。

3 OAuth2 Token 元資料(RFC7662 - OAuth2 Token Introspection)

簡單的總結來說,這個規範是為OAuth2擴充套件了一個API介面(Introspection Endpoint),讓第三方Client可以查詢上面提到的那些資訊(比如,access_token是否還有效,誰頒發的,頒發給誰的,scope又哪些等等的元資料資訊)。

比如Client發起一個如下的請求:

POST /introspect HTTP/1.1
Host: server.example.com
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer 23410913-abewfq.123483

token=2YotnFZFEjr1zCsicMWpAA&token_type_hint=access_token

 看起來和上面的撤銷Token的請求差不多,其中各項含義如下:

  1. /introspect:是Authorization Server需要提供的API地址,Client使用Post方式請求這個地址。
  2. Accept:application/json:表示Authorization Server需要返回一個JSON格式的資料。
  3. Content-Type: application/x-www-form-urlencoded:固定此格式。
  4. Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW:訪問受保護資源的授權憑證。
  5. token:必選,可以是access_token或者refresh_token的內容。
  6. token_type_hint:可選,表示token的型別,值為”access_token“或者"refresh_token"。

如果請求成功,則會返回如下的資訊:

 1 {
 2       "active": true,
 3       "client_id": "l238j323ds-23ij4",
 4       "token_type":"access_token",
 5       "username": "jdoe",
 6       "scope": "read write dolphin",
 7       "sub": "Z5O3upPC88QrAjx00dis",
 8       "aud": "https://protected.example.net/resource",
 9       "iss": "https://server.example.com/",
10       "exp": 1419356238,
11       "iat": 1419350238,
12       "nbf": 1419350238,
13       "jti": "abcdefg"
14       "extension_field": "twenty-seven"
15 }

JSON各項屬性含義如下(其中有些資訊是在JSON Web Token中定義的,參考連結有詳細的介紹):

  1. active:必須的。表示token是否還是有效的。
  2. client_id:可選的。表示token所屬的Client。比如上面的線上列印並且包郵的網站
  3. token_type:可選的。表示token的型別。對應傳遞的token_type_hint。
  4. user_name:可選的。表示token的授權者的名字。比如上面的小明
  5. scope:可選的。和上篇5.1.1 Authorization Request中的可選引數scope對應,表示授權給Client訪問的範圍,比如是相簿,而不是小明的日誌以及其他受保護資源。
  6. sub:可選的。token所屬的資源擁有者的唯一標識,JWT定義的。也就是小明的唯一識別符號。
  7. aud:可選的。token頒發給誰的,JWT定義的。
  8. iss:可選的。token的頒發者,JWT定義的。
  9. exp:可選的。token的過期時間,JWT定義的。
  10. iat:可選的。iss頒發token的時間,JWT定義的。
  11. nbf:可選的。token不會在這個時間之前被使用,JWT定義的。
  12. jti:可選的。token的唯一標識,JWT定義的。
  13. extension_field:可以自己擴充套件相關其他屬性。

其中大量的資訊都是可選的資訊,而且可以自己擴充套件需要的屬性資訊,從這些屬性中就可以解決我們上面提到的access_token對於Client不透明的問題。

我們注意到其中有很多屬於JWT定義的屬性,那麼這個JWT是什麼東西?它解決了什麼問題?

4 JSON Web Token (JWT)

簡單總結來說,JWT是一個定義一種緊湊的自包含的並且提供防篡改機制的傳遞資料的方式的標準協議。

我們先來看一個簡單的示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxpbmlhbmh1aSJ9.hnOfZb95jFwQsYj3qlgFbUu1rKpfTE6AzgXZidEGGTk

就是這麼一堆看起來像是亂碼一樣的字串。JWT由3部分構成:header.payload.signature,每個部分由“.”來分割開來。

4.1 Header

header是一個有效的JSON,其中通常包含了兩部分:token型別和簽名演算法。

{
  "alg": "HS256",
  "typ": "JWT"
}

對這個JSON採用base64編碼後就是第1部分eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

4.2 Payload

這一部分代表真正想要傳遞的資料,包含一組Claims,其中JWT預定義了一些Claim(2. Token 元資料 這一節就用到一些JWT預定義的一些Cliam)後面會介紹。關於什麼是Claim,可以參考文章末尾給的參考連結。

{
  "sub": "1234567890",
  "name": "linianhui"
}

對這個JSON採用base64編碼後就是第2部分eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxpbmlhbmh1aSJ9

4.3 Signature

這一部分是可選的,由於前面Header和Payload部分是明文的資訊,所以這一部分的意義在於保障資訊不被篡改用的,生成這部分的方式如下:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

token生成方使用header中指定的簽名演算法對“header.payload”部分進行簽名,得到的第3部分hnOfZb95jFwQsYj3qlgFbUu1rKpfTE6AzgXZidEGGTk,然後組合成一個完整的JWT字串 . 而token消費方在拿到token後, 使用同樣的簽名演算法來生成簽名,用來判斷header和payload部分有沒有被篡改過,因為簽名的金鑰是隻有通訊雙方知道的,所以可以保證這部分資訊不被第三方所篡改。

4.4 JWT的一些Claims

JWT規範中預先定義了一些Cliam,但並不是必選的,常用的有:

  1. iss(Issuer簽發者)
  2. sub(subject簽發給的受眾,在Issuer範圍內是唯一的)
  3. aud(Audience接收方)
  4. exp(Expiration Time過期時間)
  5. iat(Issued At簽發時間)等等。

如果上面這些仍無法滿足自己的需要,則可以自定義一些來使用。

4.5 JWT 應用場景

由於其採用base64來進行編碼,使得它可以安全的用在一些僅限ASCII的地方傳遞資訊,比如URL的querystring中。

比如使用者登陸後,可以把使用者的一些屬性資訊(使用者標識,是否是管理員,許可權有哪些等等可以公開的資訊)用JWT編碼儲存在cookie中,由於其自包含的性質,每次伺服器讀取到Cookie的時候就可以解析到當前使用者對應的屬性資訊,而不必再次去查詢資料庫。如果Cookie中每次都發送浪費頻寬,也可以用 Authorization: Bearer <jwttoken> 的方式附加到Request上去。

5 OAuth2 & JWT

注意到我們在 這一小節中,OAuth2返回Token的元資料的JSON,以及OAuth2中的access_token對Client是不透明的字串這件事,我們可以把access_token的元資料資訊用JWT來編碼以下,作為access_token的字串內容,這樣是不是就可以使得它對Client是透明的了。

比如我之前遇到的問題,在我使用access_token的時候有沒有過期我並不知道,其實需要藉助輔助的“expires_in”來檢查,還有其scope是哪些,也需要額外的去查詢,再比如這個access_token管理的使用者是誰,也需要額外的查詢,有了JWT呢,可以把這些都打包進去,比如:

{
    "sub":"linianhui",
    "scope":"1419356238",
    "exp":123456789,
}

然後生成一個這樣的jwt字串 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsaW5pYW5odWkiLCJzY29wZSI6IjE0MTkzNTYyMzgiLCJleHAiOjEyMzQ1Njc4OX0.ASu85ohHMSOhnxbJSJI4OKLsPlbjPs7th0Xw5-b4l1A 作為access_token的值,感覺一下子就方便了好多吧。

6 總結

以上內容均是個人的一些理解,如果錯誤之處,歡迎指正!

7 參考

OAuth2 擴充套件協議:

OAuth相關擴充套件草案:

JWT相關協議族:

相關推薦

[認證授權] 2.OAuth2授權 & JWT(JSON Web Token)

1 RFC6749還有哪些可以完善的? 1.1 撤銷Token 在上篇[認證授權] 1.OAuth2授權 中介紹到了OAuth2可以幫我們解決第三方Client訪問受保護資源的問題,但是隻提供瞭如何獲得access_token,並未說明怎麼來撤銷一個access_token。關於這部分OAuth2單獨定義

[認證授權] 2.OAuth2授權 & JWT(JSON Web Token)

har 表示 一個 wii body 是什麽 ibm 其他 user 1 RFC6749還有哪些可以完善的? 1.1 撤銷Token 在上篇[認證授權] 1.OAuth2授權 中介紹到了OAuth2可以幫我們解決第三方Client訪問受保護資源的問題,但是只提供了如何獲

.NET Core微服務之基於IdentityServer建立授權與驗證服務

上一篇我們基於IdentityServer4建立了一個AuthorizationServer,並且繼承了QuickStartUI,能夠成功獲取Token了。這一篇我們瞭解下如何整合API Service和MVC Web Application。 一、整合API Service 1.1 新增ASP.NE

Web Api Owin+Oauth2.0ClientCredentials+Jwt Token許可權認證控制

OAuth簡介 OAuth簡單說就是一種授權的協議,只要授權方和被授權方遵守這個協議去寫程式碼提供服務,那雙方就是實現了OAuth模式。 OAuth 2.0 四種授權模式: 授權碼模式(authorization code) 簡化模式(implicit) 密碼模

SCPPO二十一:系統統一身份認證的改造之路

【前言】     在上篇博文中小編為大家分享了《SCPPO:系統統一身份認證的改造之路》,由於篇幅原因其中一些東西只是簡單提了一下,也有部分內容沒有說出來;今天小編繼續接著上篇的博文,一方面為大家解上

JWT(JSON WEB TOKEN) / oauth2 / SSL

bash 字符 維護 ssl 信息 簡單 角色 ron 保存會話 1: JWT:   為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519).該token被設計為緊湊且安全的,特別適用於分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來

Spring Boot實戰之Filter實現使用JWT進行介面認證 jwt(json web token) 使用者傳送按照約定,向服務端傳送 Header、Payload 和 Signature,

Spring Boot實戰之Filter實現使用JWT進行介面認證 jwt(json web token) 使用者傳送按照約定,向服務端傳送 Header、Payload 和 Signature,幷包含認證資訊(密碼),驗證通過後服務端返回一個token,之後使用者使用該

在以太坊區塊鏈上實現認證授權和計費功能3-認證描述

2AAA(認證、授權和計費)   雲提供商提供雲資源,例如計算、網路、網路儲存資源,可以用最少的操作快速配置應用程式,而且僅需要支付消耗的資源[55]。 美國國家科學和技術研究院(NIST)[55]將這些資源分成三種模型:軟體即服務(SaaS),平臺即服務(PaaS

在以太坊區塊鏈上實現認證授權和計費功能6-選擇以太坊實現的合理性

5選擇技術的合理性   正如2.4和2.5節所討論的那樣,當前的AAA(在第2節中描述)具有各種漏洞和限制。 這些漏洞已經導致使用者資料劫持和違規、身份盜用和財務損失。 這些問題變得越來越普遍和頻繁。 這引發了當前AAA框架的安全問題。 終端使用者越來越關心他們的數字身

《compass-reference》翻譯計劃之:1.1概述和1.2所涉及技術

1.2.2. 領域模型   Compass的一個主要特性就是OSEM(物件/搜尋引擎對映)。可以採用annotation或者xml定義(或聯合使用),把豐富的領域模型對映到搜尋引擎中。想了解更多的內容,請閱讀第6章:OSEM-物件/搜尋引擎對映。   1.

ccf認證-201809-2 買菜 100分

   ccf認證-201809-2  買菜 思路:範圍不大,直接暴力 問題描述 試題編號: 201809-2 試題名稱: 買菜 時間限制: 1.

OpenID Connect Core 1.0使用授權碼流驗證

3.1 使用授權碼流驗證(Authentication using the Authorization Code Flow) 本節描述如何使用授權碼流執行驗證。當使用授權碼流時,會從令牌終結點返回的所有令牌。 授權碼流返回授權碼給客戶端,這個授權碼可以直接交換一個ID T

微信網頁授權:網頁版

轉自 http://www.cnblogs.com/0201zcr/p/5133062.html   1、OAuth2.0   OAuth(開放授權)是一個開放標準,允許使用者讓第三方應用訪問該使用者在某一網站上儲存的私密的資源(如照片,視訊,聯絡人列表),而無需將使用者名

IdentityServer4-客戶端的授權模式原理分析

原文: IdentityServer4-客戶端的授權模式原理分析(三) 在學習其他應用場景前,需要了解幾個客戶端的授權模式。首先了解下本節使用的幾個名詞 Resource Owner:資源擁有者,文中稱“user”; Client為第三方客戶端; Authorization server為授權伺服器;

CCF計算機軟體能力認證模擬試題參考答案JAVA201703 1+2

1.分蛋糕: 小明今天生日,他有n塊蛋糕要分給朋友們吃,這n塊蛋糕(編號為1到n)的重量分別為a1, a2, …, an。小明想分給每個朋友至少重量為k的蛋糕。小明的朋友們已經排好隊準備領蛋糕,對於每個朋友,小明總是先將自己手中編號最小的蛋糕分給他,當這個朋友所分得蛋

ccf認證-201809-2 買菜 100分

 ccf認證-201809-2  買菜 思路:範圍不大,直接暴力 問題描述 試題編號: 201809-2 試題名稱: 買菜 時間限制: 1.0s 記憶體限制:

微信開放平臺開發-授權、全網釋出PHP

接著看看全網釋出的測試用例怎麼做: 1、模擬粉絲觸發專用測試公眾號的事件,並推送事件訊息到專用測試公眾號,第三方平臺方開發者需要提取推送XML資訊中的event值,並在5秒內立即返回按照下述要求組裝的文字訊息給粉絲; 2、模擬粉絲髮送文字訊息給專用測試公眾號,第三方平臺方需根據文字訊息的內容進行相應的響應;

微信授權APP第三方登陸Android

前幾天負責的程式說是要加入第三方登陸的功能,雖然現在有服務商集成了第三方登陸,但是平時所用的也就微信和QQ,就自己看文件寫了,其中也遇到了一些問題,然後我把我做這個的流程貼出來,並附上對應的Demo,執行Demo前請將Android的SDK以及依賴包的版本升級到最新。1:首先如果要使用微信的第三方登陸功能,必

微信公眾號授權登入之二tp5

public function _initialize(){//檢視使用者是否授權登入過 沒有的話跳轉到授權登入頁面 if(empty(session::get('user'))) { $this->redirect('user/login');

Qt 學習之路 289:Canvas

變換 Canvas中的“變形”,主要指的是座標系的變換,而不是路徑的變換。這與 QML 元素變換非常相似,都可以實現座標系統的scale(縮放)、rotate(旋轉)和translate(平移);不同的是,變換的原點是畫布原點。例如,如果以一個路徑的中心點為定點