用户池身份验证流程 - Amazon Cognito

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

用户池身份验证流程

Amazon Cognito 包含多种对用户进行身份验证的方法。所有用户池,无论您是否有域,都可以对用户池中的用户进行身份验证API。如果您向用户群体添加域,则可以使用用户群体端点。用户池API支持各种授权模型和API请求流。

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

Public authentication

InitiateAuthRespondToAuthChallenge并且未经身份验证APIs,无法与客户端公共应用程序客户端一起使用。

Server-side authentication

AdminInitiateAuth并且AdminRespondToAuthChallenge需要IAM凭证,适用于服务器端机密应用程序客户端。

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

Authentication flow diagram showing user, mobile/web app, and user pool interactions for token issuance.

通常,您的应用程序会生成一条提示,要求您从用户那里收集信息,并在API请求中将该信息提交给 Amazon Cognito。以用户池中的一个InitiateAuth流程为例,在该流程中,您已为用户配置了多因素身份验证 (MFA)。

  1. 应用程序会提示您的用户输入用户名和密码。

  2. 您可以将用户名和密码作为参数包含在 InitiateAuth 中。

  3. Amazon Cognito 会返回 SMS_MFA 质询和会话标识符。

  4. 您的应用程序会提示您的用户从其手机中输入MFA验证码。

  5. 您将该代码和会话标识符包含在 RespondToAuthChallenge 请求中。

根据用户池的特征,您最终可能会在您的应用程序从 Amazon Cognito 检索令牌之前,响应 InitiateAuth 的几个质询。Amazon Cognito 在对每个请求的响应中都包含一个会话字符串。要将您的API请求合并到身份验证流程中,请在每个后续请求中包含对上一个请求的响应中的会话字符串。默认情况下,在会话字符串过期之前,您的用户有三分钟时间完成每项质询。要调整此时段,请更改您的应用程序客户端的 Authentication flow session duration(身份验证流程会话持续时间)。以下过程介绍如何在应用程序客户端配置中更改此设置。

注意

身份验证流程会话持续时间设置适用于使用 Amazon Cognito 用户池进行身份验证。APIAmazon Cognito 托管 UI 将多重身份验证的会话持续时间设置为 3 分钟,并将密码重置代码的会话持续时间设置为 8 分钟。

Amazon Cognito console
配置应用程序客户端身份验证流程会话持续时间 (AWS Management Console)
  1. 在您的用户群体中的 App integration(应用程序集成)选项卡上,从 App clients and analytics(应用程序客户端和分析)容器中选择您的应用程序客户端的名称。

  2. 应用程序客户端信息容器中选择编辑

  3. 将 “身份验证流会话持续时间” 的值更改为所需的SMSMFA代码有效时长,以分钟为单位。这还会更改任何用户在您的应用程序客户端中必须完成任何身份验证质询的时间。

  4. 选择 Save changes(保存更改)

Amazon Cognito API
配置应用程序客户端身份验证流程会话持续时间 (Amazon CognitoAPI)
  1. 使用 DescribeUserPoolClient 请求中您的现有用户群体设置准备 UpdateUserPoolClient 请求。您的 UpdateUserPoolClient 请求必须包含所有现有的应用程序客户端属性。

  2. 将的AuthSessionValidity值更改为您想要的SMSMFA代码有效期,以分钟为单位。这还会更改任何用户在您的应用程序客户端中必须完成任何身份验证质询的时间。

有关应用程序客户端的更多信息,请参阅使用应用程序客户端进行特定于应用程序的设置

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

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

失败登录尝试的 Amazon Cognito 锁定行为

在使用密码进行五次未经身份验证或身份IAM验证的登录尝试失败后,Amazon Cognito 会将您的用户锁定一秒钟。然后,每多一次失败的尝试,锁定持续时间将增加一倍,最长约为 15 分钟。在锁定期内进行的尝试会产生 Password attempts exceeded 异常,不会影响后续锁定期的持续时间。对于累计 n 次的失败登录尝试(不包括 Password attempts exceeded 异常),Amazon Cognito 会将您的用户锁定 2^(n-5) 秒。要将锁定重置为其 n=0 初始状态,用户必须在锁定期到期后才能成功登录,或者在锁定后连续 15 分钟的任何时间内都不得发起任何登录尝试。此行为随时可能会发生变化。此行为不适用于自定义质询,除非它们还执行基于密码的身份验证。

客户端身份验证流程

以下过程适用于您使用AWS Amplify或创建的用户客户端应用程序。AWS SDKs

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

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

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

    注意

    该应用程序使用内置的 Amazon Cognito SRP 功能生成SRP细节。 AWS SDKs

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

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

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

服务器端身份验证流程

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

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

  • 服务器端应用程序调用该AdminInitiateAuthAPI操作(而不是InitiateAuth)。此操作需要具有包含cognito-idp:AdminInitiateAuth和权限的 AWS 证书cognito-idp:AdminRespondToAuthChallenge。该操作返回必需的身份验证参数。

  • 服务器端应用程序具有身份验证参数后,它会调用该AdminRespondToAuthChallengeAPI操作(而不是RespondToAuthChallenge)。只有在您提供 AWS 凭证后,AdminRespondToAuthChallengeAPI操作才会成功。

有关使用 AWS 凭证签署 Amazon Cognito API 请求的更多信息,请参阅AWS 一般参考中的签名版本 4 签名流程

AdminInitiateAuthAdminRespondToAuthChallengeAPI操作不能接受管理员登录的 username-and-password用户凭据,除非您通过以下方式之一明确允许他们这样做:

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

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

自定义身份验证流程

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

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

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

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

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

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

内置身份验证流程和质询

Amazon Cognito 包含内置AuthFlowChallengeName值,因此标准身份验证流程可以通过安全远程密码 (SRP) 协议验证用户名和密码。它们内置 AWS SDKs了 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 会返回ChallengeName的。SMS_MFA该应用程序可以通过对 RespondToAuthChallenge 的另一次调用来提供必要的代码。

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

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

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

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

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

自定义身份验证流程还可以组合使用内置质询,例如SRP密码验证和MFA直通SMS。它可以使用自定义挑战,例如CAPTCHA或秘密问题。

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

如果要包含SRP在自定义身份验证流程中,则必须从开始SRP。

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

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

  • 接下来,应用程序必须RespondToAuthChallenge使用challengeName: PASSWORD_VERIFIERchallengeResponses地图SRP中所需的其他参数进行调用。

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

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

注意

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

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

管理员身份验证流程

身份验证的最佳做法是使用和中所述的API操作自定义身份验证流程SRP进行密码验证。 AWS SDKs使用这种方法,这种方法可以帮助他们使用SRP。但是,如果您想避免SRP计算,则可以为安全的后端服务器提供一组替代的管理API操作。对于这些后端管理员实施,请使用 AdminInitiateAuth 代替 InitiateAuth。另外,请使用 AdminRespondToAuthChallenge 代替 RespondToAuthChallenge。由于您可以以纯文本形式提交密码,因此在使用这些操作时不必SRP进行计算。示例如下:

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

这些管理员身份验证操作要求提供开发人员凭证,并使用 AWS 签名版本 4 (SigV4) 签名过程。这些操作在标准版本中可用 AWS SDKs,包括 Node.js,它便于使用 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 触发器导入用户