本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
用户池身份验证流程
Amazon Cognito 包含多种对用户进行身份验证的方法。所有用户池,无论您是否有域,都可以对用户池中的用户进行身份验证API。如果您向用户群体添加域,则可以使用用户群体端点。用户池API支持各种授权模型和API请求流。
为了验证用户的身份,除了密码之外,Amazon Cognito 还支持包含新质询类型的身份验证流程。Amazon Cognito 身份验证通常要求您按以下顺序实施两个API操作:
用户通过应答连续的质询进行身份验证,直到身份验证失败或 Amazon Cognito 向用户发放令牌。您可以在包含不同质询的流程中对 Amazon Cognito 重复这些步骤,以支持任何自定义身份验证流程。
通常,您的应用程序会生成一条提示,要求您从用户那里收集信息,并在API请求中将该信息提交给 Amazon Cognito。以用户池中的一个InitiateAuth
流程为例,在该流程中,您已为用户配置了多因素身份验证 (MFA)。
-
应用程序会提示您的用户输入用户名和密码。
-
您可以将用户名和密码作为参数包含在
InitiateAuth
中。 -
Amazon Cognito 会返回
SMS_MFA
质询和会话标识符。 -
您的应用程序会提示您的用户从其手机中输入MFA验证码。
-
您将该代码和会话标识符包含在
RespondToAuthChallenge
请求中。
根据用户池的特征,您最终可能会在您的应用程序从 Amazon Cognito 检索令牌之前,响应 InitiateAuth
的几个质询。Amazon Cognito 在对每个请求的响应中都包含一个会话字符串。要将您的API请求合并到身份验证流程中,请在每个后续请求中包含对上一个请求的响应中的会话字符串。默认情况下,在会话字符串过期之前,您的用户有三分钟时间完成每项质询。要调整此时段,请更改您的应用程序客户端的 Authentication flow session duration(身份验证流程会话持续时间)。以下过程介绍如何在应用程序客户端配置中更改此设置。
注意
身份验证流程会话持续时间设置适用于使用 Amazon Cognito 用户池进行身份验证。APIAmazon Cognito 托管 UI 将多重身份验证的会话持续时间设置为 3 分钟,并将密码重置代码的会话持续时间设置为 8 分钟。
有关应用程序客户端的更多信息,请参阅使用应用程序客户端进行特定于应用程序的设置。
您可以使用 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
-
用户将他们的用户名和密码输入到应用程序中。
-
应用程序使用用户的用户名和安全远程密码 (SRP) 详细信息调用该
InitiateAuth
操作。此API操作返回身份验证参数。
注意
该应用程序使用内置的 Amazon Cognito SRP 功能生成SRP细节。 AWS SDKs
-
应用程序调用
RespondToAuthChallenge
操作。如果调用成功,则 Amazon Cognito 返回用户的令牌,并且身份验证流程完成。如果 Amazon Cognito 需要另一个质询,则对
RespondToAuthChallenge
的调用不返回任何令牌。相反,调用会返回一个会话。 -
如果
RespondToAuthChallenge
返回会话,则应用程序会RespondToAuthChallenge
再次调用,这次是使用会话和质询响应(例如MFA代码)。
服务器端身份验证流程
如果您没有用户应用程序,而是使用 Java、Ruby 或 Node.js 安全后端或服务器端应用程序,则可以将经过身份验证的服务器端用API于 Amazon Cognito 用户池。
对于服务器端应用程序,用户池身份验证与客户端应用程序的身份验证类似,但以下情况除外:
-
服务器端应用程序调用该
AdminInitiateAuth
API操作(而不是InitiateAuth
)。此操作需要具有包含cognito-idp:AdminInitiateAuth
和权限的 AWS 证书cognito-idp:AdminRespondToAuthChallenge
。该操作返回必需的身份验证参数。 -
服务器端应用程序具有身份验证参数后,它会调用该
AdminRespondToAuthChallenge
API操作(而不是RespondToAuthChallenge
)。只有在您提供 AWS 凭证后,AdminRespondToAuthChallenge
API操作才会成功。
有关使用 AWS 凭证签署 Amazon Cognito API 请求的更多信息,请参阅AWS 一般参考中的签名版本 4 签名流程。
AdminInitiateAuth
和AdminRespondToAuthChallenge
API操作不能接受管理员登录的 username-and-password 用户凭据,除非您通过以下方式之一明确允许他们这样做:
-
调用
CreateUserPoolClient
或UpdateUserPoolClient
时,在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
自定义身份验证流程可以自定义质询和响应周期,以满足不同需求。流程从调用操作开始,该InitiateAuth
API操作指示要使用的身份验证类型并提供任何初始身份验证参数。Amazon Cognito 将使用以下类型的信息之一响应 InitiateAuth
调用:
-
用户质询及会话和参数。
-
错误(如果用户未能通过身份验证)
-
ID、访问和刷新令牌(如果
InitiateAuth
调用中提供的参数足以使用户登录)。(通常,用户或应用程序必须首先应答质询,但这必须由您的自定义代码决定。)
如果 Amazon Cognito 使用质询响应 InitiateAuth
调用,则应用程序将收集更多输入并调用 RespondToAuthChallenge
操作。此调用提供质询响应并将其传回会话。Amazon Cognito 对 RespondToAuthChallenge
的响应类似于对 InitiateAuth
调用的响应。如果用户已登录,Amazon Cognito 会提供令牌,如果用户未登录,则 Amazon Cognito 会提供另一个质询或错误。如果 Amazon Cognito 返回另一质询,则序列重复,应用程序调用 RespondToAuthChallenge
直到用户成功登录或返回错误。有关InitiateAuth
和RespondToAuthChallenge
API操作的更多详细信息,请参阅API文档。
内置身份验证流程和质询
Amazon Cognito 包含内置AuthFlow
和ChallengeName
值,因此标准身份验证流程可以通过安全远程密码 (SRP) 协议验证用户名和密码。它们内置 AWS SDKs了 Amazon Cognito 对这些流程的支持。
该流程通过将 USER_SRP_AUTH
作为 AuthFlow
发送到 InitiateAuth
开始。您还在 AuthParameters
中发送 USERNAME
和 SRP_A
值。如果 InitiateAuth
调用成功,则响应将在质询参数中包括 PASSWORD_VERIFIER
作为 ChallengeName
和 SRP_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
作为下一次质询时,身份验证流程调用CreateAuthChallenge
。CreateAuthChallenge
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_A
和challengeResult: true
的初始会话调用DefineAuthChallenge
Lambda 触发器。您的 Lambda 函数使用challengeName: PASSWORD_VERIFIER
、issueTokens: false
和failAuthentication: false
作出响应。 -
接下来,应用程序必须
RespondToAuthChallenge
使用challengeName: PASSWORD_VERIFIER
和challengeResponses
地图SRP中所需的其他参数进行调用。 -
如果 Amazon Cognito 验证了密码,
RespondToAuthChallenge
使用challengeName: PASSWORD_VERIFIER
和challengeResult: 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 函数。要使用这些操作并让它们接受明文密码,您必须在控制台中为应用程序激活这些操作。或者,您可以在调用 CreateUserPoolClient
或 UpdateUserPoolClient
时为 ExplicitAuthFlow
参数传递 ADMIN_USER_PASSWORD_AUTH
。InitiateAuth
和 RespondToAuthChallenge
操作不接受 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 触发器导入用户。