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

2 分的閱讀內容
0

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

簡短說明

當用戶端透過使用者集區對您的應用程式進行身分驗證時,Amazon Cognito 會傳送 ID 權杖。您可以在類似下列情況中手動驗證 ID 權杖:

  • 您已建立 Web 應用程式,並希望使用 Amazon Cognito 使用者集區進行身分驗證。
  • 您可以使用 Amazon Cognito 使用者集區進行身分驗證,並使用 Amazon Cognito 身分集區來擷取 AWS Security Token Service (AWS STS) 臨時憑證。AWS Lambda 會使用這些憑證進行叫用,但 Lambda 沒有最初透過使用者集區進行身分驗證的人員相關資訊。

若要取得 Amazon Cognito JSON Web 權杖 (JWT) 中包含的 Amazon Cognito 使用者詳細資料,您可以將權杖解碼,然後驗證簽章。

解決方法

AWS 發佈了下列可用來驗證 JWT 的程式庫:https://github.com/awslabs/aws-jwt-verify

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!");
}

使用者登入後,Amazon Cognito 使用者集區會傳回 JWT。JWT 是一個以 base64url 編碼的 JSON 字串 (「宣告」),其中包含有關使用者的資訊。Amazon Cognito 會傳回三個權杖:ID 權杖、存取權杖,以及重新整理權杖。ID 權杖包含 Amazon Cognito 使用者集區中定義的使用者欄位。

權杖包括三個區段:標頭、有效負載及簽章。

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

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

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

{
  "sub": "aaaaaaaa-bbbb-cccc-dddd-example",
  "aud": "xxxxxxxxxxxxexample",
  "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"
}

最後一個區段是簽章,這是標頭和有效負載的雜湊加密組合。

Amazon Cognito 會為每個使用者集區產生兩個 RSA 金鑰對。每對的私有金鑰用於簽署相應的 ID 權杖或存取權杖。公有金鑰可在以下格式的地址提供:

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

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"
    }]
}

若要驗證 Amazon Cognito JWT 的簽章,請先搜尋其金鑰 ID 與權杖標頭中的金鑰 ID 相符的公有金鑰。然後,您可以使用程式庫 (例如 aws-jwt-verify 或是 jwt.ioOpenID Foundation 所建議的程式庫) 來驗證權杖的簽章並擷取值 (例如到期日和使用者名稱)。

除了簽章之外,驗證下列項目也是最佳實務:

  • 權杖未過期。
  • 有效負載中指定的對象 ("aud") 與 Amazon Cognito 使用者集區中建立的應用程式用戶端 ID 相符。

aws-jwt-verify 程式庫代表您包含這些檢查。如需如何使用 Lambda 解碼和驗證 Amazon Cognito JWT 的更多程式碼範例,請參閱解碼和驗證 Amazon Cognito JWT 權杖


相關資訊

驗證 JSON Web 權杖

搭配使用者集區使用權杖

AWS 官方
AWS 官方已更新 2 年前