[01-jwt]C# JWT基礎知識詳解

張歐昊辰發表於2022-02-11

本文章內容翻譯自JWT官網,並融入了部分筆者的思想內容。希望給其他小夥伴在學習這部分內容時帶來一定的幫助。

一、什麼是JWT?

JWT是簡寫,全稱是JSON Web Token。

JSON Web Token(JWT)是一種開放標準(RFC 7519),它定義了一種緊湊(Compact)自包含(Self-contained)的方式,用於在各方之間以JSON物件的形式安全傳輸資訊。此資訊可以驗證和信任,因為它是經過數字簽名的。JWT可以使用金鑰(使用HMAC演算法)或使用RSAECDSA的公鑰/私鑰對進行簽名。

下面進一步解釋這個定義中的一些概念:

·緊湊(Compact):由於它的大小,它可以通過 URL、POST 引數或 HTTP 標頭內部傳送。此外,由於它的大小,它的傳輸速度很快。

·自包含(Self-contained):有效載荷(後面介紹)中包含有關使用者的所有必需資訊,可以避免多次查詢資料庫。

雖然JWT可以加密以在各方之間提供保密性,但我們將重點專注於簽名令牌。簽名的令牌可以驗證其中包含的宣告的完整性,而加密的令牌會向其他方隱藏這些宣告。當使用公鑰/私鑰對對令牌進行簽名時,簽名還證明只有持有私鑰的一方才是簽署它的一方。

二、什麼時候應該使用 JSON Web Token?

以下是一些JSON Web token非常有用的場景:

  1. 授權(Authorization):這是使用JWT最常見的場景。使用者登入後,每個後續請求都將包含JWT,從而允許使用者訪問該令牌允許的路由、服務和資源。單點登入是當今廣泛使用JWT的一項功能,因為它的開銷很小,並且能夠在不同的域中輕鬆使用。
  2. 資訊交換(Information Exchange):JSON Web Token是在各方之間安全傳輸資訊的好方法。因為可以對 JWT 進行簽名(例如,使用公鑰/私鑰對),所以您可以確定發件人就是他們所說的那個人。此外,由於使用標頭和有效負載計算簽名,您還可以驗證內容沒有被篡改。

三、JSON Web Token 結構是什麼?

在其緊湊的形式中,JSON Web token由三部分組成,三部分由點(.)分隔,它們是:

  • 標頭(Header)
  • 有效載荷(Payload)
  • 簽名(Signature)

因此,JWT結構通常如下所示:

xxxxx.yyyyy.zzzzz

接下來,讓我們把不同的部分分解一下。

1、標頭(Header)

標頭通常由兩部分組成:

  1. 令牌的型別,即JWT
  2. 正在使用的簽名演算法,例如HMAC SHA256或RSA。

例如:

{
    "alg": "HS256",  //簽名演算法

    "typ": "JWT"  //型別
}

然後,這個 JSON 被Base64Url編碼以形成 JWT 的第一部分

2、有效載荷(Payload)

令牌的第二部分是有效載荷,其中包含宣告。宣告是關於實體(通常是使用者)和附加資料的陳述。宣告分為三種型別:

  1. 註冊(registered)宣告
  2. 公開(public)宣告
  3. 私有(private )宣告
  • 註冊宣告(Registered claims):這些是一組預定義的宣告,它們不是強制性的,但建議使用,以提供一組有用的、可互操作的宣告。其中一些是: iss(發行人) exp(到期時間) sub(主題)aud(受眾)等。
請注意,宣告名稱只有三個字元長,因為JWT是緊湊的。
  • 公開宣告(Public claims):這些可以由使用 JWT 的人隨意定義。但是為了避免衝突,它們應該在IANA JSON Web Token Registry中定義,或者定義為包含抗衝突名稱空間的 URI。
  • 私人宣告(Private claims):這些是為在同意使用它們的各方之間共享資訊而建立的自定義宣告,既不是註冊宣告也不是公共宣告。

一個有效載荷的示例可能是下面這個樣子:

{
    "iss": "xx網站",  //發行人

    "name": "張歐昊辰",  //全名

    "email": "mwstars@163.com",   //郵箱

    "admin": true  //是否是管理員
}

然後,對有效負載進行Base64Url編碼以形成 JWT的第二部分

  • 請注意,對於已簽名的令牌,此資訊雖然受到保護以防篡改,但任何人都可以讀取。除非已加密,否則請勿將機密資訊放入 JWT 的有效負載或標頭元素中。

3、簽名(Signature)

要建立簽名部分,必須獲取編碼的標頭、編碼的有效負載、金鑰、標頭中指定的演算法,並對其進行簽名。

例如,如果想使用 HMAC SHA256 演算法,簽名將通過以下方式建立:

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

簽名用於驗證訊息在此過程中沒有被更改,並且在使用私鑰簽名的令牌的情況下,它還可以驗證 JWT 的傳送者就是它所說的那個人。

4、把所有的放在一起

輸出是三個用點分隔的 Base64-URL 字串,可以在 HTML 和 HTTP 環境中輕鬆傳遞,同時與基於 XML 的標準(如 SAML)相比更緊湊。

下面顯示了一個 JWT,該 JWT 具有先前的標頭和有效負載編碼,並使用金鑰簽名。 [01-jwt]C# JWT基礎知識詳解

四、JSON Web Token是如何工作?

在身份驗證中,當使用者使用其憑據成功登入時,將返回一個 JSON Web Token。由於令牌是憑據,因此必須非常小心以防止出現安全問題。通常,不應將令牌保留超過所設定的過期時間。

由於缺乏安全性,也不應該在瀏覽器儲存中儲存敏感的會話資料。

每當使用者想要訪問受保護的路由或資源時,使用者代理應該傳送 JWT,通常在Authorization標頭中使用Bearer模式。

標頭的內容應如下所示:

Authorization: Bearer <token>

在某些情況下,這可以是一種無狀態授權驗證機制,因為使用者狀態永遠不會儲存在伺服器記憶體中。伺服器的受保護路由將檢查Authorization標頭中是否存在有效的 JWT,如果存在,則允許使用者訪問受保護的資源。由於 JWT 是自包含的,所有必要的資訊都在那裡,減少了返回和轉發到資料庫的需要。

這允許完全依賴無狀態的資料 API,甚至可以向下遊服務發出請求。如果令牌在Authorization標頭中傳送,則跨域資源共享 (CORS) 不會成為問題,因為它不使用 cookie。

JSON Web 令牌的工作原理

特別注意,使用簽名令牌時,令牌中包含的所有資訊都會向使用者或其他方公開,即使他們無法更改,這也意味著不應將祕密資訊放入令牌中。

五、為什麼我們應該使用 JSON Web Tokens?

下面我們談一談JSON Web Tokens (JWT)Simple Web Tokens (SWT)Security Assertion Markup Language Tokens (SAML)相比的優勢。

  1. 由於 JSON 不像 XML 那樣冗長,因此在對其進行編碼時,它的大小也更小,這使得 JWT 比 SAML 更緊湊。這使得 JWT 成為在 HTML 和 HTTP 環境中傳遞的不錯選擇。
  2. 安全方面,SWT 只能通過使用 HMAC 演算法的共享金鑰進行對稱簽名。但是,JWT 和 SAML 令牌可以使用 X.509 證書形式的公鑰/私鑰對進行簽名。與簽署 JSON 的簡單性相比,使用 XML 數字簽名簽署 XML 而不引入隱蔽的安全漏洞是非常困難的。
  3. JSON 解析器在大多數程式語言中都很常見,因為它們直接對映到物件。相反,XML 沒有自然的文件到物件對映。這使得使用 JWT 比使用 SAML 斷言更容易。
  4. 關於使用,JWT 用於 Internet 規模。這突出了 JSON Web Token在多個平臺(尤其是移動平臺)上客戶端處理的便利性。

 下圖為編碼的 JWT 和編碼的 SAML 的長度比較

比較編碼的 JWT 和編碼的 SAML 的長度


The End……

相關文章