用户池身份验证流程 - Amazon Cognito
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

用户池身份验证流程

要验证用户的身份,在密码之外,现代身份验证流程还包含新的质询类型。Amazon Cognito 身份验证通常要求您按以下顺序实施两个 API 操作:

  1. InitiateAuth

  2. RespondToAuthChallenge

用户通过应答连续的质询进行身份验证,直到身份验证失败或 Amazon Cognito 向用户发放令牌。您可以在包含不同质询的流程中对 Amazon Cognito 重复这些步骤,以支持任何自定义身份验证流程。

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

您还可以在安全后端服务器上对用户使用管理员身份验证流程。您可以使用用户迁移身份验证流来进行用户迁移,而无需用户重置其密码。

注意

用户可以尝试登录,但未能正确登录五次后,Amazon Cognito 将临时锁定用户。锁定时间从一秒开始,并呈指数级增长,在每次后续失败尝试之后增加一倍,最长可达 15 分钟。在临时锁定期间,Amazon Cognito 忽略登录尝试,这些尝试不会启动新的锁定期。在用户等待 15 分钟后,Amazon Cognito 会重置临时锁定。此行为随时可能会发生变化。

客户端身份验证流程

以下过程适用于您使用 Amazon Mobile SDK for Android、Amazon Mobile SDK for iOS 或者 Amazon SDK for JavaScript 创建的用户客户端应用程序:

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

  2. 应用程序使用用户的用户名和安全远程密码(SRP)详细信息调用 InitiateAuth 操作。

    此 API 操作返回身份验证参数。

    注意

    该应用程序使用 Amazon 开发工具包内置的 Amazon Cognito SRP 功能生成 SRP 详细信息。

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

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

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

服务器端身份验证流程

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

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

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

  • 服务器端应用程序获得身份验证参数后,它就会调用 AdminRespondToAuthChallenge API 操作(而不是 RespondToAuthChallenge)。AdminRespondToAuthChallenge API 操作仅在您提供了 Amazon 管理员权限时才会成功。

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

  • 调用 CreateUserPoolClientUpdateUserPoolClient 时,在 ExplicitAuthFlow 参数中包含 ALLOW_ADMIN_USER_PASSWORD_AUTH(以前称为 ADMIN_NO_SRP_AUTH)。

  • ALLOW_ADMIN_USER_PASSWORD_AUTH 添加到您的应用程序客户端的 Authentication flow(身份验证流程)列表中。在您的用户池中的 App integration(应用程序集成)选项卡上的 App clients and analytics(应用程序客户端和分析)下配置应用程序客户端。有关更多信息,请参阅配置用户池应用程序客户端

自定义身份验证流程

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

注意

您不能在自定义身份验证流中使用高级安全功能。有关更多信息,请参阅向用户池添加高级安全

自定义身份验证流程可以自定义质询和响应周期,以满足不同需求。该流程首先调用 InitiateAuth API 操作,该调用指示将使用的身份验证类型并提供了所有初始身份验证参数。Amazon Cognito 将使用以下类型的信息之一响应 InitiateAuth 调用:

  • 用户质询及会话和参数。

  • 错误(如果用户未能通过身份验证)

  • ID、访问和刷新令牌(如果 InitiateAuth 调用中提供的参数足以使用户登录)。(通常,用户或应用程序必须首先应答质询,但这必须由您的自定义代码决定。)

如果 Amazon Cognito 使用质询响应 InitiateAuth 调用,则应用程序将收集更多输入并调用 RespondToAuthChallenge 操作。此调用提供质询响应并将其传回会话。Amazon Cognito 对 RespondToAuthChallenge 的响应类似于对 InitiateAuth 调用的响应。如果用户已登录,Amazon Cognito 会提供令牌,如果用户未登录,则 Amazon Cognito 会提供另一个质询或错误。如果 Amazon Cognito 返回另一质询,则序列重复,应用程序调用 RespondToAuthChallenge 直到用户成功登录或返回错误。有关 InitiateAuthRespondToAuthChallenge API 操作的详细信息,请参阅 API 文档

内置身份验证流程和质询

Amazon Cognito 包含适用于标准身份验证流程的内置 AuthFlowChallengeName 值,以通过安全远程密码(SRP)协议验证用户名和密码。Amazon 开发工具包具有对 Amazon Cognito 这些流程的内置支持。

该流程通过将 USER_SRP_AUTH 作为 AuthFlow 发送到 InitiateAuth 开始。您还在 AuthParameters 中发送 USERNAMESRP_A 值。如果 InitiateAuth 调用成功,则响应将在质询参数中包括 PASSWORD_VERIFIER 作为 ChallengeNameSRP_B。然后,应用程序将使用 ChallengeResponses 中的 PASSWORD_VERIFIER ChallengeName 和必要参数调用 RespondToAuthChallenge。如果 RespondToAuthChallenge 调用成功并且用户登录,则 Amazon Cognito 将发布令牌。如果您为用户激活了多重验证 (MFA),Amazon Cognito 返回 SMS_MFAChallengeName。该应用程序可以通过对 RespondToAuthChallenge 的另一次调用来提供必要的代码。

自定义身份验证流程和质询

应用程序可以启动自定义身份验证流程,具体方法是:调用 InitiateAuth 并将 CUSTOM_AUTH 用作 Authflow。借助自定义身份验证流程,三个 Lambda 触发器控制响应的质询和验证。

  • DefineAuthChallenge Lambda 触发器将以前的质询和响应的会话数组作为输入。然后,它生成下一个质询名称和布尔值,指示用户是否通过身份验证并且应被授予令牌。此 Lambda 触发器是一个状态机,可通过质询控制用户的路径。

  • CreateAuthChallenge Lambda 触发器将质询名称作为输入并生成质询和参数以评估响应。当 DefineAuthChallenge 返回 CUSTOM_CHALLENGE 作为下一次质询时,身份验证流程调用 CreateAuthChallengeCreateAuthChallenge Lambda 触发器在质询元数据参数中传递下一个类型的质询。

  • VerifyAuthChallengeResponse Lambda 函数会评估响应并返回布尔值以表明响应是否有效。

自定义身份验证流程还可以使用内置质询的组合,例如 SRP 密码验证和通过短信进行的 MFA。它可以使用自定义质询,如验证码或秘密问题。

在自定义身份验证流程中使用 SRP 密码验证

如果您希望将 SRP 包含在自定义身份验证流程中,则您必须开始使用 SRP。

  • 要在自定义流程中启动 SRP 密码验证,应用程序将 CUSTOM_AUTH 作为 Authflow 来调用 InitiateAuth。在 AuthParameters 映射 中,来自应用程序的请求包括 SRP_A:(SRP A 值)和 CHALLENGE_NAME: SRP_A

  • CUSTOM_AUTH 流会使用 challengeName: SRP_AchallengeResult: true 的初始会话调用 DefineAuthChallenge Lambda 触发器。您的 Lambda 函数使用 challengeName: PASSWORD_VERIFIERissueTokens: falsefailAuthentication: false 作出响应。

  • 接下来,该应用程序必须使用 challengeName: PASSWORD_VERIFIERchallengeResponses 映射中 SRP 所需的其它参数调用 RespondToAuthChallenge

  • 如果 Amazon Cognito 验证了密码,RespondToAuthChallenge 使用 challengeName: PASSWORD_VERIFIERchallengeResult: true 的第二个会话调用 DefineAuthChallenge Lambda 触发器。此时,DefineAuthChallenge Lambda 触发器可以使用 challengeName: CUSTOM_CHALLENGE 响应来开启自定义质询。

  • 如果为用户启用了 MFA,则在 Amazon Cognito 验证密码后,您的用户将被要求设置 MFA 或使用 MFA 登录。

注意

Amazon Cognito 托管的登录网页无法激活 自定义身份验证质询 Lambda 触发器

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

管理员身份验证流程

身份验证的最佳实践是使用 自定义身份验证流程 中所述的 API 操作,以使用 SRP 进行密码验证。Amazon 开发工具包使用该方法,这一方法帮助它们使用 SRP。但是,如果您希望避免 SRP 计算,还可以使用另一组专为在安全后端服务器上使用的管理员 API 操作。对于这些后端管理员实施,请使用 AdminInitiateAuth 代替 InitiateAuth。另外,请使用 AdminRespondToAuthChallenge 代替 RespondToAuthChallenge。由于您能够以明文形式提交密码,因此在使用这些操作时不必进行 SRP 计算。示例如下:

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

这些管理员身份验证操作要求提供开发人员凭证,并使用 Amazon 签名版本 4 (SigV4) 签名过程。这些操作在 Node.js 等标准 Amazon SDK 中可用,便于用于 Lambda 函数。要使用这些操作并让它们接受明文密码,您必须在控制台中为应用程序激活这些操作。或者,您可以在调用 CreateUserPoolClientUpdateUserPoolClient 时为 ExplicitAuthFlow 参数传递 ADMIN_USER_PASSWORD_AUTHInitiateAuthRespondToAuthChallenge 操作不接受 ADMIN_USER_PASSWORD_AUTH AuthFlow

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

注意

由于后端管理员实施使用管理员身份验证流程,因此流不支持设备跟踪。在您启用设备跟踪时,管理员身份验证成功,但任何对刷新访问令牌的调用均会失败。

用户迁移身份验证流程

用户迁移 Lambda 触发器可帮助您将用户从旧式用户管理系统迁移到您的用户池。如果选择 USER_PASSWORD_AUTH 身份验证流程,则用户在用户迁移过程中无需重置密码。此流程在身份验证期间通过加密的 SSL 连接向服务发送用户的密码。

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

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

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