使用 Lambda 触发器自定义用户池工作流
Amazon Cognito 使用 Amazon Lambda 函数来修改用户池的身份验证行为。您可以将您的用户池配置为在用户首次注册之前、完成身份验证之后以及两者之间的几个阶段自动调用 Lambda 函数。您的函数可以修改身份验证流程的默认行为,发出 API 请求以修改您的用户池或其他 Amazon 资源,以及与外部系统通信。您的 Lambda 函数中的代码是您自己的。Amazon Cognito 会将事件数据发送到您的函数,等待函数处理数据,而且在大多数情况下,预计会出现一个响应事件,该事件反映您要对会话进行的任何更改。
在请求和响应事件系统中,您可以引入自己的身份验证质询、在用户池与其他身份存储之间迁移用户、自定义消息以及修改 JSON Web 令牌 (JWT)。
Lambda 触发器可以自定义用户在您的用户池中启动操作后 Amazon Cognito 向用户提供的响应。例如,您可以阻止原本会成功的用户登录。他们还可以对您的 Amazon 环境、外部 API、数据库或身份存储执行运行时操作。例如,迁移用户触发器可以将外部操作与 Amazon Cognito 中的更改相结合:您可以在外部目录中查找用户信息,然后根据该外部信息设置新用户的属性。
当您为用户池分配 Lambda 触发器时,Amazon Cognito 会中断其原定设置流程,以从您的函数请求信息。Amazon Cognito 生成 JSON 事件并将其传递给您的函数。该事件包含有关您的用户旨在创建用户账户、登录、重置密码或更新属性的请求的信息。然后,您的函数有机会采取行动,或者将事件原封不动地发回。未经修改返回的事件会通知您的用户池继续执行对该事件的默认操作。例如,您的注册前触发器可以自动确认用户是否使用 PreSignUp_SignUp 触发器源,但对于外部用户和管理员创建的用户,返回的事件保持不变。
下表总结了使用 Lambda 触发器自定义用户池操作的一些方法:
| 用户池流 | 操作 | 描述 |
|---|---|---|
|
自定义身份验证流程 |
定义身份验证质询。 | 确定自定义身份验证流中的下一个挑战 |
| 创建身份验证质询。 | 在自定义身份验证流中创建挑战 | |
| 验证身份验证质询响应。 | 确定响应在自定义身份验证流中是正确的 | |
| 身份验证事件 | 身份验证前 Lambda 触发器 | 自定义验证以接受或拒绝登录请求 |
| 身份验证后 Lambda 触发器 | 记录自定义分析的事件 | |
| 令牌生成前 Lambda 触发器 | 增加或隐藏令牌声明 | |
| 注册 | 注册前 Lambda 触发器 | 执行接受或拒绝注册请求的自定义验证 |
| 确认后 Lambda 触发器 | 为自定义分析添加自定义欢迎消息或事件日志记录 | |
| 迁移用户 Lambda 触发器 | 将用户从现有用户目录迁移到用户池 | |
| 消息 | 自定义消息 Lambda 触发器 | 执行消息的高级自定义和本地化 |
| 令牌创建 | 令牌生成前 Lambda 触发器 | 添加或删除 ID 令牌和访问令牌中的属性 |
| 电子邮件和 SMS 第三方提供商 | 自定义发件人 Lambda 触发器 | 使用第三方提供商发送 SMS 和电子邮件 |
主题
有关 Lambda 触发器的需知信息
在为 Lambda 函数准备用户池时,请考虑以下各项:
-
Amazon Cognito 发送到 Lambda 触发器的事件可能会随着新功能推出而发生变化。响应和请求元素在 JSON 层次结构中的位置可能改变,或者可能会添加元素名称。在 Lambda 函数中,您预期会收到本指南中介绍的输入元素键值对,但是更严格的输入验证可能会导致您的函数失败。
-
您可以从 Amazon Cognito 发送到某些触发器的多个事件版本中选择一个。某些版本可能需要您接受对 Amazon Cognito 定价的更改。有关定价的更多信息,请参阅 Amazon Cognito 定价
。要在令牌生成前 Lambda 触发器中自定义访问令牌,您必须使用精简版之外的功能计划对用户池进行配置,并更新 Lambda 触发器配置以使用事件版本 2。 -
Amazon Cognito 会同步调用 Lambda 函数,但 自定义发件人 Lambda 触发器 除外。Amazon Cognito 调用您的 Lambda 函数时,函数必须在 5 秒内响应。如果并非如此,并且可以重试调用,则 Amazon Cognito 会重试调用。3 次尝试失败后,该函数将超时。您无法更改此 5 秒钟超时值。有关更多信息,请参阅《Amazon Lambda 开发人员指南》中的 Lambda 编程模型。
Amazon Cognito 不会重试返回调用错误且 HTTP 状态代码为 500-599 的函数调用。这些代码表示配置问题导致 Lambda 无法启动该函数。有关更多信息,请参阅 Amazon Lambda 中的错误处理和自动重试。
-
您无法在 Lambda 触发器配置中声明函数版本。默认情况下,Amazon Cognito 用户池会调用您的函数的最新版本。但是,您可以将函数版本与别名相关联,并将触发器
LambdaArn设置为 CreateUserPool 或 UpdateUserPool API 请求中的别名 ARN。此选项在Amazon Web Services 管理控制台中不可用。要了解有关别名的更多信息,请参阅《Amazon Lambda 开发人员指南》中的 Lambda 函数别名。 -
如果您删除某个 Lambda 触发器,必须更新用户池中的相应触发器。例如,如果您删除身份验证后触发器,则必须在相应用户池中将 Post authentication(身份验证后)触发器设置为 none(无)。
-
如果您的 Lambda 函数没有向 Amazon Cognito 返回请求和响应参数,或者返回错误,则身份验证事件将无法成功。您可以在函数中返回错误,以阻止用户注册、身份验证、令牌生成或其身份验证流程中任何其他调用 Lambda 触发器的阶段。
托管登录将返回 Lambda 触发器生成的错误作为登录提示上方的错误文本。Amazon Cognito 用户池 API 以
格式返回触发器错误。最佳做法是,仅在 Lambda 函数中生成您希望用户看到的错误。使用输出方法(如[trigger]failed with error[error text from response]print())将任何敏感或调试信息记录到 CloudWatch Logs 中。有关示例,请参阅注册前示例:如果用户名少于五个字符,则拒绝注册。 -
您可以将另一个 Amazon Web Services 账户中的 Lambda 函数添加为用户池的触发器。您必须使用 CreateUserPool 和 UpdateUserPool API 操作或它们在 Amazon CloudFormation 和 Amazon CLI 中的等效操作添加跨账户触发器。您无法在 Amazon Web Services 管理控制台中添加跨账户函数。
-
当您在 Amazon Cognito 控制台中添加 Lambda 触发器时,Amazon Cognito 会向您的函数添加一个基于资源的策略,允许您的用户池调用该函数。当您在 Amazon Cognito 控制台之外创建 Lambda 触发器(包括跨账户函数)时,您必须向 Lambda 函数的基于资源的策略添加权限。您添加的权限必须允许 Amazon Cognito 代表您的用户池调用函数。您可以从 Lambda 控制台添加权限或者使用 Lambda AddPermission API 操作。
Lambda 基于资源的策略示例
以下 Lambda 基于资源的策略示例授予 Amazon Cognito 有限调用 Lambda 函数的能力。Amazon Cognito 只能在代表
aws:SourceArn中的用户池和aws:SourceAccount条件中的账户时才能调用函数。
添加用户池 Lambda 触发器
使用控制台添加用户池 Lambda 触发器
-
使用 Lambda 控制台
创建 Lambda 函数。有关 Lambda 函数的更多信息,请参阅《Amazon Lambda 开发人员指南》https://docs.amazonaws.cn/lambda/latest/dg/。 -
转到 Amazon Cognito 控制台
,然后选择 User Pools(用户池)。 -
从列表中选择一个现有用户池,或创建一个用户池。
-
选择扩展菜单并找到 Lambda 触发器。
-
选择 Add a Lambda trigger(添加 Lambda 触发器)。
-
基于您希望自定义的身份验证阶段,选择 Lambda 触发器 Category(类别)。
-
选择 Assign Lambda function(分配 Lambda 函数),然后在同一个 Amazon Web Services 区域 中选择一个函数作为您的用户池。
注意
如果您的 Amazon Identity and Access Management (IAM) 凭证有权更新 Lambda 函数,Amazon Cognito 将添加基于 Lambda 资源的策略。通过此政策,Amazon Cognito 可以调用您选择的函数。如果登录凭证没有足够的 IAM 权限,则必须单独更新基于资源的策略。有关更多信息,请参阅有关 Lambda 触发器的需知信息。
-
选择保存更改。
-
您可以在 Lambda 控制台中使用 CloudWatch 记录您的 Lambda 函数。有关更多信息,请参阅访问适用于 Lambda 的 CloudWatch Logs。
用户池 Lambda 触发器事件
Amazon Cognito 将事件信息传递给 Lambda 函数。随后,Lambda 函数将相同事件对象随同响应中的任何更改返回给 Amazon Cognito。如果您的函数返回未经修改的输入事件,Amazon Cognito 将继续执行默认行为。下面显示了所有 Lambda 触发器输入事件的通用参数。有关特定于触发器的事件语法,请查阅本指南中各触发器对应章节中的事件架构。
用户池 Lambda 触发器通用参数
- version
-
您的 Lambda 函数的版本号。
- triggerSource
-
触发 Lambda 函数的事件的名称。有关每个 triggerSource 的说明,请参阅将 Lambda 触发器连接到用户池功能操作。
- 区域
-
Amazon Web Services 区域,作为
AWSRegion实例。 - userPoolId
-
用户池的 ID。
- userName
-
当前用户的用户名。
- callerContext
-
有关请求和代码环境的元数据。它包含 awsSdkVersion 和 clientId 字段。
- awsSdkVersion
-
生成请求的 Amazon SDK 版本。
- clientId
-
用户池应用程序客户端的 ID。
- request
-
您的用户的 API 请求的详细信息。它包括以下字段以及触发器特定的任何请求参数。例如,Amazon Cognito 发送到预身份验证触发器的事件也将包含一个
userNotFound参数。当您的用户尝试使用未注册的用户名登录时,您可以处理此参数的值以执行自定义操作。- userAttributes
-
用户属性名称和值的一个或多个键值对,例如
"email": "john@example.com"。
- 响应
-
此参数在原始请求中不包含任何信息。Lambda 函数必须将整个事件返回给 Amazon Cognito,并将任何返回参数添加到
response。要查看您的函数可以包含哪些返回参数,请参阅要使用的触发器的文档。
客户端元数据
您可以在 API 操作和令牌端点请求中向 Lambda 触发器函数提交自定义参数。通过客户端元数据,您的应用程序可以收集有关请求来源环境的额外信息。当您将客户端元数据传递给您的 Lambda 函数时,它们可以处理这些附加数据,并将其用于日志记录或自定义身份验证流。客户端元数据是您选择和设计的字符串对,采用 JSON 键值格式。
客户端元数据使用案例示例
-
在注册时将地理位置数据传递给注册前触发器,并阻止来自非预期位置的登录请求。
-
将租户 ID 数据传递给自定义质询触发器,并向来自不同业务单位的客户发出不同的质询。
-
将用户的令牌传递给令牌生成前触发器,并生成日志,记录 M2M 请求所代表的主体。有关示例请求,请参阅基本授权的客户端凭证。
以下是向注册前触发器传递客户端元数据的一个示例。
机器对机器(M2M)客户端凭证的客户端元数据
您可以在 M2M 请求中传递客户端元数据。客户端元数据是来自用户或应用程序环境的附加信息,可影响令牌生成前 Lambda 触发器的结果。在涉及用户主体的身份验证操作中,您可以在 AdminRespondToAuthChallenge 和 RespondToAuthChallenge API 请求的请求正文中,将客户端元数据传递给令牌生成前触发器。由于应用程序通过直接向 令牌端点 发出请求来执行为 M2M 生成访问令牌的流程,因此它们的模型不同。在客户端凭证令牌请求的 POST 正文中,传递一个 aws_client_metadata 参数,其值为客户端元数据对象经 URL 编码(x-www-form-urlencoded)后的字符串。有关示例请求,请参阅基本授权的客户端凭证。以下是传递键值对 {"environment": "dev", "language": "en-US"} 的参数的示例。
aws_client_metadata=%7B%22environment%22%3A%20%22dev%22,%20%22language%22%3A%20%22en-US%22%7D
临时用户属性:validationData
一些身份验证操作也有一个 validationData 参数。与客户端元数据一样,这是一个将 Amazon Cognito 不会自动收集的外部信息传递给 Lambda 触发器的机会。验证数据字段旨在为您的 Lambda 函数提供注册和登录操作中的额外用户上下文。SignUp 和 AdminCreateUser 将 validationData 传递给注册前触发器。InitiateAuth 和 AdminInitiateAuth 会在 API 请求正文中传递 ClientMetadata,并将其作为输入事件中的 validationData,发送给身份验证前和迁移用户触发器。
要将 API 操作映射到它们可以将客户端元数据传递到的函数,请参阅后面有关触发器源的章节。
将 API 操作连接到 Lambda 触发器
以下部分介绍 Amazon Cognito 从您的用户池中的活动调用的 Lambda 触发器。
当您的应用程序通过 Amazon Cognito 用户池 API、托管登录或用户池端点登录用户时,Amazon Cognito 会根据会话上下文调用您的 Lambda 函数。有关 Amazon Cognito 用户池 API 和用户池端点的更多信息,请参阅了解 API、OIDC 和托管登录页面身份验证。以下各节中的表格描述了导致 Amazon Cognito 调用函数的事件,以及 Amazon Cognito 在请求中包含的 triggerSource 字符串。
Amazon Cognito API 中的 Lambda 触发器
下表描述了 Lambda 触发器的源字符串,当您的应用程序创建、登录或更新本地用户时,Amazon Cognito 可以调用这些触发器。
| API 操作 | Lambda 触发器 | 触发器源 |
|---|---|---|
| 注册前 |
|
|
| 令牌生成前 |
|
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
| 注册前 |
|
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
| 确认后 |
|
|
| 身份验证前 |
|
|
| 身份验证后 |
|
|
| 定义身份验证质询 |
|
|
| 创建身份验证质询 |
|
|
| 验证身份验证质询 |
|
|
| 令牌生成前 |
|
|
| 迁移用户 |
|
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
| 身份验证后 |
|
|
| 定义身份验证质询 |
|
|
| 创建身份验证质询 |
|
|
| 验证身份验证质询 |
|
|
| 令牌生成前 |
|
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
| 迁移用户 |
|
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
| 确认后 |
|
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
| 令牌生成前 |
|
托管登录中的 Amazon Cognito 本地用户的 Lambda 触发器
下表描述了 Lambda 触发器的源字符串,当本地用户使用托管登录来登录到您的用户池时,Amazon Cognito 可以调用这些触发器。
| 托管登录 URI | Lambda 触发器 | 触发器源 |
|---|---|---|
/signup |
注册前 |
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
/confirmuser |
确认后 |
|
/login |
身份验证前 |
|
| 令牌生成前 |
|
|
| 迁移用户 |
|
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
/forgotpassword |
迁移用户 |
|
| 自定义消息 |
|
|
| 自定义电子邮件发件人 |
|
|
| 自定义短信发件人 |
|
|
/confirmforgotpassword |
确认后 |
|
针对联合身份用户的 Lambda 触发器
您可以使用以下 Lambda 触发器,为使用联合身份提供商登录的用户自定义用户池工作流。
注意
联合用户可以使用托管登录进行登录,也可以生成对对端点授权的请求,以静默方式将它们重新导向到其身份提供者登录页面。您无法使用 Amazon Cognito 用户池 API 登录联合用户。
| 登录事件 | Lambda 触发器 | 触发器源 |
|---|---|---|
| 首次登录 | 注册前 |
|
| 确认后 |
|
|
| 令牌生成前 |
|
|
| 后续登录 | 身份验证前 |
|
| 身份验证后 |
|
|
| 令牌生成前 |
|
联合身份登录不会在您的用户池中调用任何 自定义身份验证质询 Lambda 触发器、迁移用户 Lambda 触发器、自定义消息 Lambda 触发器 或者自定义发件人 Lambda 触发器。
将 Lambda 触发器连接到用户池功能操作
每个 Lambda 触发器都在您的用户池中发挥功能作用。例如,触发器可以修改您的注册流程,或添加自定义身份验证质询。Amazon Cognito 发送到 Lambda 函数的事件可以反映构成该函数角色的多个操作之一。例如,当您的用户注册时以及当您创建用户时,Amazon Cognito 会调用预注册触发器。同一功能角色的每个不同案例都有其自身的 triggerSource 值。您的 Lambda 函数可以根据调用该函数的操作以不同的方式处理传入事件。
当事件对应于触发器源时,Amazon Cognito 还会调用所有分配的函数。例如,当用户登录到您分配了迁移用户和预身份验证触发器的用户池时,他们会同时激活这两个触发器。
| 触发器 | triggerSource 值 | 事件 |
|---|---|---|
| 注册前 | PreSignUp_SignUp |
注册前。 |
| 注册前 | PreSignUp_AdminCreateUser |
在管理员创建新用户时做好注册准备。 |
| 注册前 | PreSignUp_ExternalProvider |
适用于外部身份提供商的注册前。 |
| 确认后 | PostConfirmation_ConfirmSignUp |
注册后确认。 |
| 确认后 | PostConfirmation_ConfirmForgotPassword |
忘记密码后确认。 |
| 身份验证前 | PreAuthentication_Authentication |
身份验证前。 |
| 身份验证后 | PostAuthentication_Authentication |
身份验证后。 |
| 触发器 | triggerSource 值 | 事件 |
|---|---|---|
| 定义身份验证质询 | DefineAuthChallenge_Authentication |
定义身份验证质询。 |
| 创建身份验证质询 | CreateAuthChallenge_Authentication |
创建身份验证质询。 |
| 验证身份验证质询 | VerifyAuthChallengeResponse_Authentication |
验证身份验证质询响应。 |
| 触发器 | triggerSource 值 | 事件 |
|---|---|---|
| 令牌生成前 | TokenGeneration_HostedAuth |
Amazon Cognito 从您的托管登录页面对用户进行身份验证。 |
| 令牌生成前 | TokenGeneration_Authentication |
用户身份验证或令牌刷新已完成。 |
| 令牌生成前 | TokenGeneration_NewPasswordChallenge |
管理员创建用户。当用户必须更改临时密码时,Amazon Cognito 调用此项。 |
| 令牌生成前 | TokenGeneration_AuthenticateDevice |
结束用户设备身份验证。 |
| 令牌生成前 | TokenGeneration_RefreshTokens |
用户尝试刷新身份和访问令牌时调用。 |
| 触发器 | triggerSource 值 | 事件 |
|---|---|---|
| 用户迁移 | UserMigration_Authentication |
用户登录时进行迁移。 |
| 用户迁移 | UserMigration_ForgotPassword |
忘记密码流程中的用户迁移。 |
| 触发器 | triggerSource 值 | 事件 |
|---|---|---|
| 自定义消息 | CustomMessage_SignUp |
用户在您的用户池中注册时的自定义消息。 |
| 自定义消息 | CustomMessage_AdminCreateUser |
当您创建用户作为管理员并且 Amazon Cognito 向他们发送临时密码时的自定义消息。 |
| 自定义消息 | CustomMessage_ResendCode |
现有用户请求新的确认码时的自定义消息。 |
| 自定义消息 | CustomMessage_ForgotPassword |
用户请求重置密码时的自定义消息。 |
| 自定义消息 | CustomMessage_UpdateUserAttribute |
用户更改其电子邮件地址或电话号码并且 Amazon Cognito 发送验证码时的自定义消息。 |
| 自定义消息 | CustomMessage_VerifyUserAttribute |
用户添加电子邮件地址或电话号码并且 Amazon Cognito 发送验证码时的自定义消息。 |
| 自定义消息 | CustomMessage_Authentication |
配置了 SMS MFA 的用户登录时的自定义消息。 |
| 触发器 | triggerSource 值 | 事件 |
|---|---|---|
| 自定义发件人 |
|
用户在您的用户池中注册。 |
| 自定义发件人 |
|
您以管理员身份创建用户并且 Amazon Cognito 向他们发送临时密码。 |
| 自定义发件人 |
|
用户请求重置密码。 |
| 自定义发件人 |
|
用户更改其电子邮件地址或电话号码并且 Amazon Cognito 发送验证码。 |
| 自定义发件人 |
|
用户添加电子邮件地址或电话号码并且 Amazon Cognito 发送验证码。 |
| 自定义发件人 |
|
配置了短信、电子邮件 MFA 或 OTP 的用户登录。 |
| 自定义发件人 | CustomEmailSender_AccountTakeOverNotification |
您的威胁防护设置对用户的登录尝试采取自动操作并且针对风险级别的操作包括通知。 |