使用 Amazon Cognito 用户池进行身份验证
Amazon Cognito 包含多种对用户进行身份验证的方法。用户可以使用密码和 WebAuthn 通行密钥登录。Amazon Cognito 可以通过电子邮件或短信向他们发送一次性密码。您可以实现 Lambda 函数,以编排您自己的质询与响应序列。这些是身份验证流程。在身份验证流程中,用户提交一个密钥,Amazon Cognito 验证该密钥后,会颁发 JSON Web 令牌(JWT),供应用程序使用 OIDC 库进行处理。本章将介绍如何在不同的应用程序环境中,为您的用户池和应用程序客户端配置各种身份验证流程。您将了解使用托管登录的托管登录页面的选项,以及如何在 Amazon SDK 中构建您自己的逻辑和前端。
所有用户池(无论您是否具有域)都可以在用户池 API 中对用户进行身份验证。如果您向用户池添加域,则可以使用用户池端点。用户池 API 支持针对 API 请求的各种授权模型和请求流程。
为了验证用户的身份,Amazon Cognito 支持多种身份验证流程,这些流程除了密码之外,还结合了其他类型的质询,例如电子邮件和短信一次性密码以及通行密钥。
实现身份验证流程
无论您是使用托管登录,还是通过 Amazon SDK 定制的应用程序前端来进行身份验证,都必须为应用程序客户端配置您希望实现的身份验证类型。以下信息介绍了如何在应用程序客户端和应用程序中设置身份验证流程。
有关用户池身份验证的需知信息
在使用 Amazon Cognito 用户池设计身份验证模型时,请考虑以下信息。
- 托管登录与托管 UI 中的身份验证流程
-
托管登录提供的身份验证选项比经典托管 UI 更多。例如,无密码身份验证和通行密钥身份验证仅在托管登录中可用。
- 仅在 Amazon SDK 身份验证中可用的自定义身份验证流程
-
您无法在托管登录或经典托管 UI 中执行自定义身份验证流程,也无法使用 Lambda 触发器进行自定义身份验证。自定义身份验证仅支持使用 Amazon SDK 进行身份验证时使用。
- 通过外部身份提供者(IdP)登录的托管登录
-
您无法在使用 Amazon SDK 进行身份验证时通过第三方 IdP 登录用户。必须实现托管登录或经典托管 UI,将用户重定向到 IdP,然后在应用程序中使用 OIDC 库处理返回的身份验证对象。有关托管登录的更多信息,请参阅用户池托管登录。
- 无密码身份验证对其他用户功能的影响
-
在用户池和应用程序客户端中激活使用一次性密码或通行密钥的无密码登录,会影响用户的创建和迁移。当无密码登录启用时:
-
管理员无需密码即可创建用户。默认的邀请消息模板将不再包含
{###}密码占位符。有关更多信息,请参阅以管理员身份创建用户账户。 -
对于基于 SDK 的 SignUp 操作,用户在注册时无需提供密码。而在托管登录和托管 UI 中,即使允许无密码身份验证,在注册页面中仍会要求用户输入密码。有关更多信息,请参阅注册并确认用户账户。
-
从 CSV 文件导入的用户,只要其属性中包含可用于无密码登录选项的电子邮件地址或电话号码,即可立即使用无密码方式登录,而无需重置密码。有关更多信息,请参阅通过 CSV 文件将用户导入用户池中。
-
无密码身份验证不会调用用户迁移 Lambda 触发器。
-
使用无密码方式作为第一重身份验证因素登录的用户,无法在其会话中添加多重身份验证(MFA)因素。仅基于密码的身份验证流支持 MFA。
-
- 通行密钥的依赖方 URL 不能位于公共后缀列表中
-
您可以使用自己拥有的域名(例如
www.example.com)作为通行密钥配置中的依赖方(RP)ID。此配置旨在支持运行在您自有域上的定制应用程序。公共后缀列表(PSL)包含受保护的高层级域。当您尝试将 RP URL 设置为 PSL 中的域时,Amazon Cognito 会返回错误。
身份验证会话流程持续时间
根据用户池的功能,您的应用程序可能需要在从 Amazon Cognito 获取令牌之前,对 InitiateAuth 和 RespondToAuthChallenge 进行多次质询响应。Amazon Cognito 在对每个请求的响应中都包含一个会话字符串。要将您的 API 请求合并到身份验证流程中,请在每个后续请求中包含来自上一个请求的响应中的会话字符串。默认情况下,在会话字符串过期之前,您的用户有三分钟时间完成每项质询。要调整此时段,请更改您的应用程序客户端的 Authentication flow session duration(身份验证流程会话持续时间)。以下过程介绍如何在应用程序客户端配置中更改此设置。
注意
身份验证流程会话持续时间设置适用于使用 Amazon Cognito 用户池 API 进行身份验证。托管登录将多重身份验证的会话持续时间设置为 3 分钟,并将密码重置验证码的会话持续时间设置为 8 分钟。
有关应用程序客户端的更多信息,请参阅特定于应用程序的应用程序客户端设置。
失败登录尝试的锁定行为
当用户连续五次输入错误密码尝试登录时(无论这些请求是通过未经身份验证的 API 操作还是通过 IAM 授权的 API 操作发起的),Amazon Cognito 会将该用户锁定一秒钟。然后,每多一次失败的尝试,锁定持续时间将增加一倍,最长约为 15 分钟。
在锁定期内进行的尝试会产生 Password attempts exceeded 异常,不会影响后续锁定期的持续时间。对于累计 n 次的失败登录尝试(不包括 Password attempts exceeded 异常),Amazon Cognito 会将您的用户锁定 2^(n-5) 秒。要将锁定重置为其 n=0 初始状态,用户必须在锁定期到期后才能成功登录,或者在锁定后连续 15 分钟的任何时间内都不得发起任何登录尝试。此行为随时可能会发生变化。此行为不适用于自定义质询,除非它们还执行基于密码的身份验证。
身份验证会话示例
下图和分步指南展示了一个典型场景:用户登录应用程序。示例应用程序向用户提供多种登录选项。用户通过输入凭证选择其中一种,随后提供额外的身份验证因素,最终完成登录。
设想一个应用程序,其登录页面允许用户通过用户名和密码登录、请求通过电子邮件发送的一次性验证码,或选择指纹验证选项。
-
登录提示:您的应用程序显示一个主页,其中包含一个登录按钮。
-
请求登录:用户选择登录。您的应用程序从 Cookie 或缓存中检索其用户名,或提示其输入用户名。
-
请求选项:您的应用程序请求用户的登录选项,方法是使用
USER_AUTH流程发起InitiateAuthAPI 请求,获取用户的可用登录方式。 -
发送登录选项:Amazon Cognito 返回
PASSWORD、EMAIL_OTP和WEB_AUTHN。该响应包含一个会话标识符,供您在下一个响应中回传。 -
显示选项:您的应用程序显示 UI 元素,供用户选择输入用户名和密码、获取一次性验证码,或扫描指纹。
-
选择选项/输入凭证:用户输入其用户名和密码。
-
发起身份验证:您的应用程序通过
RespondToAuthChallengeAPI 请求提交用户的登录信息,确认使用用户名密码进行登录,并提供相应的用户名和密码。 -
验证凭证:Amazon Cognito 确认用户提供的凭证。
-
额外质询:该用户已配置使用于身份验证器应用程序进行多重身份验证。Amazon Cognito 返回
SOFTWARE_TOKEN_MFA质询。 -
质询提示:您的应用程序显示一个表单,请求用户输入其身份验证器应用程序生成的基于时间的一次性密码(TOTP)。
-
回答质询:用户提交该 TOTP。
-
响应质询:您的应用程序在另一个
RespondToAuthChallenge请求中提供用户的 TOTP。 -
验证质询响应:Amazon Cognito 确认用户提交的验证码,并确定您的用户池未针对当前用户配置额外的质询。
-
颁发令牌:Amazon Cognito 返回 ID、访问和刷新 JSON Web 令牌(JWT)。用户的初始身份验证完成。
-
存储令牌:您的应用程序缓存用户的令牌,以便后续引用用户数据、授权资源访问,并在令牌过期时进行更新。
-
呈现授权内容:您的应用程序根据用户的身份和角色判断其资源访问权限,并提供相应的应用程序内容。
-
访问内容:用户已登录并开始使用该应用程序。
-
使用过期令牌请求内容:稍后,用户请求一个需要授权的资源。但用户缓存的令牌已过期。
-
刷新令牌:您的应用程序使用用户保存的刷新令牌发起
InitiateAuth请求。 -
颁发令牌:Amazon Cognito 返回新的 ID 和访问 JWT。用户的会话在无需再次输入凭证的情况下安全地完成刷新。
您可以使用 Amazon Lambda 触发器来自定义用户进行身份验证的方式。作为身份验证流程的一部分,这些触发器将发布并验证自己的质询。
您还可以在安全后端服务器上对用户使用管理员身份验证流程。您可以使用用户迁移身份验证流程来进行用户迁移,而无需用户重置其密码。