驗證 JSON Web 權杖 - Amazon Cognito

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

驗證 JSON Web 權杖

JSON Web 權杖 (JWTs) 可以輕鬆解碼、讀取和修改。修改後的存取權杖會產生權限提升的風險。修改後的 ID 權杖會產生模擬的風險。您的應用程式信任使用者集區作為權杖發行者,但如果使用者在傳輸中攔截權杖,該怎麼辦? 您必須確保您的應用程式收到與 Amazon Cognito 發行相同的權杖。

Amazon Cognito 會發出權杖,這些權杖使用 OpenID Connect (OIDC) 規格的一些完整性和機密性功能。使用者集區權杖表示對過期時間、發行者和數位簽章等物件的有效性。以 .分隔的 簽章是字符驗證的關鍵元件JWT,也就是 分隔的 的第三個和最後一個區段。惡意使用者可修改權杖,但如果您的應用程式擷取公有金鑰並比較簽章,則不相符。從JWTsOIDC身分驗證處理的任何應用程式都必須在每次登入時執行此驗證操作。

在此頁面上,我們會提出一些一般和特定建議來驗證 JWTs。應用程式開發涵蓋各種程式設計語言和平台。由於 Amazon Cognito 的實作OIDC足以接近公有規格,因此您選擇的開發人員環境中任何信譽良好的JWT程式庫都可以處理您的驗證需求。

這些步驟描述驗證使用者集區 JSON Web 權杖 (JWT)。

必要條件

您的程式庫SDK、 或 軟體架構可能已經處理本節中的任務。 AWS SDKs 在應用程式中提供 Amazon Cognito 使用者集區權杖處理和管理工具。 AWS Amplify 包含擷取和重新整理 Amazon Cognito 權杖的函數。

如需詳細資訊,請參閱下列頁面。

許多程式庫可用於解碼和驗證 JSON Web 權杖 (JWT)。如果您想要手動處理權杖以進行伺服器端API處理,或者如果您使用其他程式設計語言,這些程式庫可以提供協助。請參閱用於使用JWT權杖 的程式庫 OpenID 基礎清單

使用 驗證權杖 aws-jwt-verify

在 Node.js 應用程式中, AWS 建議 aws-jwt-verify 程式庫,以驗證您的使用者傳遞至應用程式的權杖中的參數。使用 aws-jwt-verify 時,您可以使用您要驗證一或多個使用者集區的宣告值填入 CognitoJwtVerifier。它可以檢查的一些值包括以下內容。

如需可在 Node.js 應用程式或 AWS Lambda 授權方中使用的詳細資訊和範例程式碼,請參閱 aws-jwt-verify 在 上 GitHub。

了解和檢查權杖

將權杖檢查與應用程式整合之前,請考慮 Amazon Cognito 如何組合 JWTs。從使用者集區擷取範例權杖。對它們進行詳細解碼和檢查以了解它們的特徵,並確定您要驗證的內容和時間。例如,您可能想在一種情況下檢查群組成員資格,而在另一種情況下檢查範圍。

下列各節說明當您準備應用程式JWTs時手動檢查 Amazon Cognito 的程序。

確認 的結構 JWT

JSON Web 權杖 (JWT) 包含三個區段,其間具有 .(點) 分隔符號。

標頭

Amazon Cognito 用來簽署權杖的金鑰 IDalgkid和RSA演算法 。Amazon Cognito 使用 RS256alg 簽署權杖。kid 是使用者集區所持有之 2048 位元RSA私有簽署金鑰的截斷參考。

承載

權杖宣告。在 ID 權杖中,宣告包括使用者屬性和有關使用者集區 (iss) 和應用程式用戶端 (aud) 的資訊。在存取權杖中,承載包括範圍、群組成員資格、您的使用者集區為 iss,以及您的應用程式用戶端為 client_id

簽章

簽章不像標頭和承載那樣是可解碼的 base64。它是衍生自簽署金鑰和參數的RSA256識別符,您可以在 JWKS 上觀察URI。

標頭和承載是 base64 編碼的 JSON。您可以透過解碼為起始字元 { 的開頭字元 eyJ 以識別它們。如果您的使用者JWT向您的應用程式顯示 base64 編碼,且其格式不是 [JSON Header].[JSON Payload].[Signature],則它不是有效的 Amazon Cognito 權杖,您可以將其捨棄。

驗證 JWT

JWT 簽章是標頭和承載的雜湊組合。Amazon Cognito 會為每個使用者集區產生兩對RSA密碼編譯金鑰。一個私有金鑰簽署存取權杖,另一個簽署 ID 權杖。

驗證JWT權杖的簽章
  1. 解碼 ID 權杖。

    OpenID Foundation 也會維護程式庫清單,以供使用JWT字符

    您也可以使用 AWS Lambda 解碼使用者集區 JWTs。如需詳細資訊,請參閱使用 解碼和驗證 Amazon Cognito JWT權杖 AWS Lambda

  2. 比較本機金鑰 ID (kid) 與公有 kid

    1. 下載並存放使用者集區的對應公有 JSON Web 金鑰 (JWK)。它可作為 JSON Web 金鑰集 () 的一部分使用JWKS。您可以jwks_uriURI為您的環境建構下列項目來找到它:

      https://cognito-idp.<Region>.amazonaws.com/<userPoolId>/.well-known/jwks.json

      如需 JWK和 JWK 集的詳細資訊,請參閱 JSON Web 金鑰 (JWK)

      注意

      Amazon Cognito 可能會輪換使用者集區中的簽署金鑰。最佳做法是在應用程式中快取公有金鑰,使用 kid 做為快取金鑰,並定期重新整理快取。將應用程式所收到權杖中的 kid 與您的快取進行比較。

      如果您收到的權杖具有正確的發行者但 kid 不同,則 Amazon Cognito 可能已輪換簽署金鑰。從您的使用者集區 jwks_uri 端點重新整理快取。

      這是範本 jwks.json 檔案:

      { "keys": [{ "kid": "1234example=", "alg": "RS256", "kty": "RSA", "e": "AQAB", "n": "1234567890", "use": "sig" }, { "kid": "5678example=", "alg": "RS256", "kty": "RSA", "e": "AQAB", "n": "987654321", "use": "sig" }] }
      金鑰 ID (kid)

      kid 是提示,指出使用哪個金鑰來保護權杖的 JSON Web Signature (JWS)。

      演算法 (alg)

      alg 標頭參數代表用來保護 ID 權杖安全的加密演算法。使用者集區使用RS256密碼編譯演算法,這是 SHA-256 的RSA簽章。如需 的詳細資訊RSA,請參閱RSA密碼編譯

      金鑰類型 (kty)

      kty 參數會識別與金鑰搭配使用的密碼編譯演算法系列,例如本範例中的「RSA」。

      RSA 指數 (e

      e 參數包含RSA公有金鑰的指數值。它以 Base64urlUInt 編碼值表示。

      RSA 模數 (n

      n 參數包含RSA公有金鑰的模數值。它以 Base64urlUInt 編碼值表示。

      用途 (use)

      這個 use 參數描述公開金鑰的用途。在這個範例中,usesig 代表簽章。

    2. 在公有 JSON Web 金鑰中搜尋kid符合您 kid的 JWT。

  3. 使用JWT程式庫,將發行者的簽章與權杖中的簽章進行比較。發行者簽章衍生自 jwks.json kid中符合權杖 的公有金鑰 RSA (模數 "n")。 kid您可能需要先將 JWK 轉換為 PEM 格式。下列範例採用 JWTJWK和 ,並使用 Node.js 程式庫 jsonwebtoken 來驗證JWT簽章:

    Node.js
    var jwt = require('jsonwebtoken'); var jwkToPem = require('jwk-to-pem'); var pem = jwkToPem(jwk); jwt.verify(token, pem, { algorithms: ['RS256'] }, function(err, decodedToken) { });

驗證宣告

驗證JWT宣告
  1. 利用下列其中一種方法確認權杖尚未過期。

    1. 解碼權杖,並將 exp 宣告與目前時間進行比較。

    2. 如果您的存取權杖包含aws.cognito.signin.user.admin宣告,請將請求傳送至API類似 的 GetUser。API 如果您的權杖已過期,使用存取權杖授權的 請求會傳回錯誤。

    3. 在對 userInfo 端點 提出的請求中顯示存取權杖。如果您的權杖已過期,您的請求將會傳回錯誤。

  2. 在 ID 權杖中的 aud 宣告和在存取權杖中的 client_id 宣告應符合在 Amazon Cognito 使用者集區建立的應用程式用戶端 ID。

  3. 發行者 (iss) 宣告應該符合您的使用者集區。例如,在 us-east-1 區域中建立的使用者集區會有以下 iss 值:

    https://cognito-idp.us-east-1.amazonaws.com/<userpoolID>.

  4. 檢查 token_use宣告。

    • 如果您只在 Web API操作中接受存取權杖,則其值必須為 access

    • 如果您只使用 ID 權杖,其值必須是 id

    • 如果是同時使用 ID 權杖和存取權杖,token_use 宣告必須是 idaccess

您現在可以信任權杖內部的宣告。