如何解碼和驗證 Amazon Cognito JSON Web 權杖的簽章?

2 分的閱讀內容
0

我想要使用 Amazon Cognito 使用者集區作為應用程式的身分驗證方法。我想要一種安全的方法來驗證用戶端發送到我的應用程式的 ID 和存取權杖。

簡短說明

當用戶端使用使用者集區對應用程式進行驗證時,Cognito 會傳送 JSON Web 權杖 (JWT) 供您解碼、讀取和修改。要從 JWT 取得 Cognito 用戶端詳細資訊,請解碼權杖並驗證簽章。

**重要:**在授予資源存取權之前,您必須驗證簽章。

解決方法

驗證 Congnito 是否發行 JWT

在 JavaScript 中使用以下程式碼:

import { CognitoJwtVerifier } from "aws-jwt-verify";

// Verifier that expects valid access tokens:
const verifier = CognitoJwtVerifier.create({
  userPoolId: "user_pool_id",
  tokenUse: "access",
  clientId: "client_id",
});

try {
  const payload = await verifier.verify(
    "eyJraWQeyJhdF9oYXNoIjoidk..." // the JWT as string
  );
  console.log("Token is valid. Payload:", payload);
} catch {
  console.log("Token not valid!");
}

**注意:**使用您的使用者集區 ID 取代 user_pool_id,並使用您的應用程式用戶端 ID 取代 client_id。對於 ID 權杖,請將 TokenUse 欄位更新為 「id」。如需可用參數清單,請參閱 GitHub 網站上的 aws-jwt-verify

如果您使用其他程式設計語言,請參閱 JWT 網站上的 jwt.io 程式庫或 OpenID 網站上的 OpenID Connect 程式庫。如需程式碼範例,請參閱 GitHub 網站上的 解碼和驗證 Amazon Cognito JWT 權杖

Cognito 會傳回三個權杖:ID 權杖存取權杖,以及重新整理權杖。如果您使用 REST API、AWS Amplify 或 AWS SDK 來驗證使用者,則您將取得所有三個權杖。

對於 Cognito 託管的 UI,您取得的權杖取決於您使用的授權授予類型。如果您使用隱含授予,則只會取得存取權限和 ID 權杖。授權程式碼授予授與返回存取權限、ID 和重新整理權杖。用戶端憑證授予僅會返回存取權杖。

存取和 ID 權杖包括標頭、有效負載和簽名。用戶端無法解碼或驗證重新整理權杖。

以下是範例 ID 權杖標頭。標頭包含金鑰 ID ("kid") 以及用於簽署權杖的演算法 ("alg")。RS256 演算法是具有 SHA-256 的 RSA 簽名:

{
  "kid": "key_id_example=",
  "alg": "RS256"
}

以下是有效負載的範例,其中包含有關使用者的資訊,以及權杖建立和到期的時間戳記:

{
  "sub": "aaaaaaaa-bbbb-cccc-dddd-example",
  "aud": "audience_example",
  "email_verified": true,
  "token_use": "id",
  "auth_time": 1500009400,
  "iss": "https://cognito-idp.ap-southeast-2.amazonaws.com/ap-southeast-2_example",
  "cognito:username": "anaya",
  "exp": 1500013000,
  "given_name": "Anaya",
  "iat": 1500009400,
  "email": "anaya@example.com"
}

簽章是標頭和有效負載的雜湊和加密組合。

Cognito 會為每個使用者集區產生兩個 RSA 金鑰對。每對的私有金鑰用於加密簽署相應的 ID 權杖或存取權杖。您可以在下列位置的地址找到公開金鑰:

https://cognito-idp.region.amazonaws.com/userPoolId/.well-known/jwks.json

注意:使用使用者集區所在的 AWS 區域取代區域,並使用使用者集區 ID 取代 userPoolId

JSON 檔案 (jwks.json) 的結構格式如下:

{    "keys": [{
        "alg": "RS256",
        "e": "AQAB",
        "kid": "abcdefghijklmnopqrsexample=",
        "kty": "RSA",
        "n": "lsjhglskjhgslkjgh43lj5h34lkjh34lkjht3example",
        "use": "sig"
    }, {
        "alg":
        "RS256",
        "e": "AQAB",
        "kid": "fgjhlkhjlkhexample=",
        "kty": "RSA",
        "n": "sgjhlk6jp98ugp98up34hpexample",
        "use": "sig"
    }]
}

若要驗證 Cognito JWT 的簽章,搜尋其金鑰 ID 與權杖標頭相符的公有金鑰。使用不同的程式庫來驗證權杖的簽名並擷取值,例如到期和使用者名稱。

最佳實務是驗證權杖沒有過期。此外,請確定有效負載中的受眾 ("aud") 與您在 Amazon Cognito 使用者集區中建立的應用程式用戶端 ID 相符。aws-jwt-verify 程式庫會為您檢查這些值。如需詳細資訊,請參閱 GitHub 網站上的 aws-jwt-verify

快取公開金鑰

由於 JWKS 端點中的公開金鑰很少輪換,因此您不需要在每次驗證權杖時從端點下載它們。相反地,請下載公開金鑰並在您使用 JWT 權杖驗證邏輯的本機上快取它們。

"kid" 是公開金鑰的唯一識別碼。要驗證 JWT 權杖,請檢查本機快取以確定快取中的權杖標頭是否有**"kid"**。如果沒有快取,請從 JWKS 端點下載公開金鑰並更新您的快取。

使用不同的方法來檢查權杖的到期或撤銷狀態

您可以撤銷重新整理權杖並使存取權杖無效,但無法撤銷 ID 權杖。JWT 驗證程式庫驗證權杖的到期,但程式庫不檢查權杖的撤銷狀態。撤銷狀態檢查需要進行伺服器端的檢查。

相關資訊

了解使用者集區 JSON 網路權杖 (JWT)

如何使用 AWS CLI 在 Amazon Cognito 中撤銷 JWT 權杖?

AWS 官方
AWS 官方已更新 4 個月前