我希望使用 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 Lambda 解码并验证 Amazon Cognito JWT 的代码示例,请参阅 GitHub 网站上的解码并验证 Amazon Cognito JWT 令牌

在用户登录后,Amazon Cognito 用户池会返回 JWT,这是一个 Base64 编码的 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 匹配的公有密钥。然后,您可以使用库(如 jwt.ioOpenID Foundation 推荐的库)来验证令牌的签名并提取值(如过期时间和用户名)。

​除签名外,最好还确认:

  • 令牌尚未过期。
  • 负载中所列的受众 (“aud”) 与 Amazon Cognito 用户池中创建的应用程序客户端 ID 相匹配。

有关如何使用 AWS Lambda 解码并验证 Amazon Cognito JWT 的代码示例,请参阅解码并验证 Amazon Cognito JWT 令牌


此页面对您有帮助吗? |

返回 AWS Support 知识中心

需要帮助?访问 AWS 支持中心

发布时间:2018 年 2 月 13 日

更新时间:2018 年 7 月 24 日