Amazon Cognito
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

用户池身份验证流程

除密码外,现代身份验证流程还包含新的质询类型,来验证用户身份。我们将身份验证归纳为两个通用步骤,这两个步骤通过两个 API 实现:InitiateAuthRespondToAuthChallenge

用户通过回答连续的质询进行身份验证,直到身份验证失败或用户获得令牌。通过这两个可以重复执行以包含不同质询的步骤,我们可以支持任何自定义身份验证流程。

您可以使用 AWS Lambda 触发器自定义身份验证流程。作为身份验证流程的一部分,这些触发器将发布并验证自己的质询。

您还可以使用设计为在安全的后端服务器上使用的管理员身份验证流程,以及用户迁移身份验证流程,以允许用户迁移,而无需您的用户重置其密码。

客户端身份验证流程

以下是用户池身份验证对使用 适用于 Android 的 AWS 移动软件开发工具包、AWS Mobile SDK for iOS 或适用于 JavaScript 的 AWS 开发工具包创建的最终用户客户端应用程序的工作方式:

  1. 用户将他们的用户名和密码输入到应用程序中。

  2. 应用程序使用用户名和 SRP 详细信息调用 InitiateAuth 方法。

    该方法返回身份验证参数。

    注意

    应用程序通过使用 Android、iOS 和 JavaScript 开发工具包中支持的 Amazon Cognito SRP 来生成 SRP 详细信息。

  3. 应用程序调用 RespondToAuthChallenge 方法。如果该方法调用成功,则返回用户的令牌,并且身份验证流程完成。

    如果需要另一个质询,则不返回令牌。相反,对 RespondToAuthChallenge 的调用会返回一个会话。

  4. 如果 RespondToAuthChallenge 返回会话,则应用程序再次调用 RespondToAuthChallenge,这次是使用会话和质询响应 (例如 MFA 代码)。

服务器身份验证流程

如果您没有最终用户应用程序,而是使用 Java、Ruby 或 Node.js 安全后端或服务器端应用程序,则可以对 Amazon Cognito 用户池使用经过身份验证的服务器端 API。

对于服务器端应用程序,用户池身份验证与客户端应用程序的身份验证类似,但以下情况除外:

  • 服务器端应用程序调用 AdminInitiateAuth API (而不是 InitiateAuth)。此方法需要 AWS 管理员凭证。该方法返回身份验证参数。

  • 一旦拥有身份验证参数,应用程序将调用 AdminRespondToAuthChallenge API (而不是 RespondToAuthChallenge),该 API 也需要 AWS 管理员凭证。

AdminInitiateAuthAdminRespondToAuthChallenge API 无法接受用于管理员登录的用户名和密码用户凭证,除非您通过执行以下操作之一明确启用它们:

  • 在服务器端应用程序对 CreateUserPoolClientUpdateUserPoolClient 的调用中为 ExplicitAuthFlow 参数传递 ADMIN_NO_SRP_AUTHENTICATION

  • Create a user pool (创建用户池) 的 Apps (应用程序) 选项卡中选择 Enable sign-in API for server-based authentication (ADMIN_NO_SRP_AUTH) (对基于服务器的身份验证启用登录 API (ADMIN_NO_SRP_AUTH))。有关更多信息,请参阅 配置用户池应用程序客户端

自定义身份验证流程

Amazon Cognito 用户池还支持自定义身份验证流程,这可以帮助您使用 AWS Lambda 触发器创建基于质询/响应的身份验证模型。

自定义身份验证流程旨在允许一系列可自定义以满足不同需求的质询和响应周期。该流程以 InitiateAuth API 调用开始,该调用指示将使用的身份验证类型并提供所有初始身份验证参数。Amazon Cognito 将使用以下任一内容响应 InitiateAuth 调用:

  • ID 令牌、访问令牌和刷新令牌 (如果用户已登录)

  • 用户质询及会话和参数

  • 错误 (如果用户未能进行身份验证)

如果 Amazon Cognito 使用质询来响应 InitiateAuth 调用,则应用程序将收集更多输入并调用 RespondToAuthChallenge API,从而提供质询响应并传递回会话。Amazon Cognito 响应 RespondToAuthChallenge 调用的方式与响应 InitiateAuth 调用类似,提供令牌 (如果用户已登录)、另一质询或错误。如果返回另一质询,则序列以应用程序调用 RespondToAuthChallenge 重复,直到用户登录或返回错误。API 文档中提供了有关 InitiateAuthRespondToAuthChallenge API 的更多详细信息。

Amazon Cognito 有一些适用于标准身份验证流程的内置 AuthFlowChallengeName 值,以通过安全远程密码 (SRP) 协议验证用户名和密码。此流程内置在适用于 Amazon Cognito 的 iOS、Android 和 JavaScript 开发工具包中。概括来说,此流程从以下操作开始:将 USER_SRP_AUTH 作为 AuthFlow 发送给 InitiateAuth 并随附 AuthParameters 中的 USERNAMESRP_A 值。如果 InitiateAuth 调用成功,则响应将在质询参数中包括 PASSWORD_VERIFIER 作为 ChallengeNameSRP_B。然后,应用程序将使用 ChallengeResponses 中的 PASSWORD_VERIFIER ChallengeName 和必要参数调用 RespondToAuthChallenge。如果 RespondToAuthChallenge 调用成功并且用户已登录,则将返回令牌。如果针对用户启用了多重验证 (MFA),则会返回 SMS_MFAChallengeName,并且应用程序会通过再一次调用 RespondToAuthChallenge 提供必要代码。

应用程序可以启动自定义身份验证流程,具体方法是:调用 InitiateAuth 并将 CUSTOM_AUTH 用作 Authflow。借助自定义身份验证流程,可通过三个 AWS Lambda 触发器控制响应的质询和验证。DefineAuthChallenge Lambda 触发器将上一质询和响应的会话数组作为输入,并输出下一质询名称和布尔值,该值指明用户已进行身份验证 (并且应该已被授予令牌) 或身份验证失败。此 Lambda 触发器是一个状态机,可通过质询控制用户的路径。CreateAuthChallenge Lambda 触发器将质询名称作为输入,并生成质询和参数来评估响应。当 DefineAuthChallenge 返回 CUSTOM_CHALLENGE 作为下一质询时,系统会调用 CreateAuthChallenge,并且在质询元数据参数中传递下一质询类型。VerifyAuthChallengeResponse Lambda 函数会评估响应并返回布尔值以指明响应是否有效。

此外,自定义身份验证流程还可以使用内置质询和自定义质询的组合,其中内置质询包括通过 SMS 的 SRP 密码验证和 MFA 等,自定义质询包括 CAPTCHA 或保密问题等。如果您希望将 SRP 包含在自定义身份验证流程中,则您需要开始使用它。要启动 SRP 密码验证,DefineAuthChallenge Lambda 触发器需要在身份验证参数映射中返回 SRP_A 作为质询名称和 SRP_A。验证密码后,系统会通过上一质询数组中的 PASSWORD_VERIFIER 再次调用 DefineAuthChallenge Lambda 触发器。如果针对用户启用了 MFA,则 MFA 会自动完成。

有关 Lambda 触发器的更多信息,包括示例代码,请参阅 使用 Lambda 触发器自定义用户池工作流

注意

Amazon Cognito 托管的登录网页不支持自定义身份验证流程。

管理员身份验证流程

描述 自定义身份验证流程 并使用 SRP 进行密码验证的 API 是推荐的身份验证方法。iOS、Android 和 JavaScript 开发工具包均基于上述方法,让使用 SRP 变得很轻松。但是,如果您希望避免 SRP 计算,还可以使用另一组专为在安全后端服务器上使用而设计的管理员 API。对于这些后端管理实施,AdminInitiateAuth 用于替代 InitiateAuth,并且 AdminRespondToAuthChallenge 用于替代 RespondToAuthChallenge。在使用这些 API 时,密码能够以纯文本的形式提交,因此无需进行 SRP 计算。例如,

AdminInitiateAuth Request { "AuthFlow":"ADMIN_NO_SRP_AUTH", "AuthParameters":{ "USERNAME":"<username>", "PASSWORD":"<password>" }, "ClientId":"<clientId>", "UserPoolId":"<userPoolId>" }

这些管理员身份验证 API 要求提供开发人员凭证,并使用 AWS 签名版本 4 (SigV4) 签名过程。这些 API 在 Node.js 等标准 AWS 开发工具包中可用,便于在 Lambda 函数中使用。要使用这些 API 并让它们接受纯文本密码,您必须在控制台中针对应用程序启用它们或在调用中将 ExplicitAuthFlow 参数的 ADMIN_NO_SRP_AUTH 传递到 CreateUserPoolClientUpdateUserPoolClient。对于 InitiateAuthRespondToAuthChallenge API,系统不接受 ADMIN_NO_SRP_AUTH AuthFlow

AdminInitiateAuth 响应 ChallengeParameters 中,USER_ID_FOR_SRP 属性 (如果提供) 将包含用户的实际用户名而不是别名 (如电子邮件地址或电话号码)。在 ChallengeResponses 中,当您调用 AdminRespondToAuthChallenge 时,您需要在 USERNAME 参数中传递此用户名。

注意

管理员身份验证流程专为后端管理员实施而设计,因此,不支持设备跟踪。如果启用了设备跟踪,管理员身份验证成功,但任何对刷新访问令牌的调用均会失败。

用户迁移身份验证流程

可使用用户迁移 Lambda 触发器轻松地将用户从传统用户管理系统迁移到您的用户池。为避免您的用户在用户迁移期间重置密码,请选择 USER_PASSWORD_AUTH 身份验证流程,该流程在身份验证期间通过加密 SSL 连接将用户密码发送至服务。

所有用户均完成迁移后,我们建议您切换为更安全的 SRP 流程,该流程不通过网络发送任何密码。

要了解有关 Lambda 触发器的更多信息,请参阅 使用 Lambda 触发器自定义用户池工作流

有关使用 Lambda 触发器迁移用户的更多信息,请参阅 利用用户迁移 Lambda 触发器将用户导入用户池