在授权代码授予中使用 PKCE - Amazon Cognito
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在授权代码授予中使用 PKCE

Amazon Cognito 在授权代码授予中支持代码交换的证明密钥(PKCE)身份验证。PKCE 是公共客户端的 OAuth 2.0 授权代码授予的扩展。PKCE 可防止兑换拦截的授权代码。

Amazon Cognito 如何使用 PKCE

要开始使用 PKCE 进行身份验证,您的应用程序必须生成一个唯一的字符串值。此字符串是代码验证程序,Amazon Cognito 使用该密钥值将请求初始授权授予的客户端与使用授权代码交换令牌的客户端进行比较。

您的应用程序必须对代码验证器字符串应用 SHA256 哈希值,并将结果编码为 base64。将经过哈希处理的字符串作为请求正文中的 code_challenge 参数传递到 对端点授权。当您的应用程序将授权代码交换为令牌时,它必须以纯文本形式包括代码验证程序字符串,作为请求正文中的 code_verifier 参数传递到 令牌端点。Amazon Cognito 对代码验证器执行相同的 hash-and-encode操作。Amazon Cognito 仅在确定代码验证程序产生的代码质询与在授权请求中收到的代码质询相同时,才会返回 ID 令牌、访问令牌和刷新令牌。

使用 PKCE 实现授权授予流程
  1. 打开 Amazon Cognito 控制台。如果出现提示,请输入您的 Amazon 凭据。

  2. 选择用户池

  3. 从列表中选择一个现有用户池,或创建一个用户池。如果您创建了用户池,则在向导期间将提示您设置应用程序客户端并配置托管登录。

    1. 如果您创建了新的用户池,请在引导式设置期间设置应用程序客户端并配置托管登录。

    2. 如果您配置现有用户池,请添加公共应用程序客户端(如果尚未添加)。

  4. 生成一个随机的字母数字字符串 [通常是一个全局唯一标识符(UUID)],以便为 PKCE 创建代码质询。此字符串是您将在发送给 令牌端点 的请求中提交的 code_verifier 参数的值。

  5. 用 SHA256 算法对code_verifier字符串进行哈希处理。将哈希操作的结果编码为 base64。此字符串是您将在发送给 对端点授权 的请求中提交的 code_challenge 参数的值。

    以下 Python 示例生成 code_verifier 并计算 code_challenge

    #!/usr/bin/env python3 import random from base64 import urlsafe_b64encode from hashlib import sha256 from string import ascii_letters from string import digits # use a cryptographically strong random number generator source rand = random.SystemRandom() code_verifier = ''.join(rand.choices(ascii_letters + digits, k=128)) code_verifier_hash = sha256(code_verifier.encode()).digest() code_challenge = urlsafe_b64encode(code_verifier_hash).decode().rstrip('=') print(f"code challenge: {code_challenge}") print(f"code verifier: {code_verifier}")

    以下是 Python 脚本的示例输出:

    code challenge: Eh0mg-OZv7BAyo-tdv_vYamx1boOYDulDklyXoMDtLg code verifier: 9D-aW_iygXrgQcWJd0y0tNVMPSXSChIc2xceDhvYVdGLCBk-JWFTmBNjvKSdOrjTTYazOFbUmrFERrjWx6oKtK2b6z_x4_gHBDlr4K1mRFGyE8yA-05-_v7Dxf3EIYJH
  6. 使用 PKCE 的授权码授权请求完成托管登录登录。以下是示例 URL:

    https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?response_type=code&client_id=1example23456789&redirect_uri=https://www.example.com&code_challenge=Eh0mg-OZv7BAyo-tdv_vYamx1boOYDulDklyXoMDtLg&code_challenge_method=S256
  7. 收集授权 code 并使用令牌端点将其兑换为令牌。以下是一个示例请求:

    POST /oauth2/token HTTP/1.1 Host: mydomain.auth.us-east-1.amazoncognito.com Content-Type: application/x-www-form-urlencoded Content-Length: 296 redirect_uri=https%3A%2F%2Fwww.example.com& client_id=1example23456789& code=7378f445-c87f-400c-855e-0297d072ff03& grant_type=authorization_code& code_verifier=9D-aW_iygXrgQcWJd0y0tNVMPSXSChIc2xceDhvYVdGLCBk-JWFTmBNjvKSdOrjTTYazOFbUmrFERrjWx6oKtK2b6z_x4_gHBDlr4K1mRFGyE8yA-05-_v7Dxf3EIYJH
  8. 查看响应。响应将包含 ID 令牌、访问令牌和刷新令牌。有关使用 Amazon Cognito 用户池令牌的更多信息,请参阅了解用户池 JSON 网络令牌 (JWTs)