自定义发件人 Lambda 触发器 - Amazon Cognito
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

自定义发件人 Lambda 触发器

Lambda 触发器 CustomEmailSenderCustomSMSSender 支持在用户池中使用第三方电子邮件和短信通知。您可以选择 SMS 和电子邮件提供商,通过 Lambda 函数代码向用户发送通知。当 Amazon Cognito 向用户发送邀请、MFA 代码、确认码、验证码或临时密码时,这些事件会激活您配置的 Lambda 函数。Amazon Cognito 将代码和临时密码(密钥)发送到您激活的 Lambda 函数。Amazon Cognito 使用 Amazon KMS 客户托管密钥和 Amazon Encryption SDK加密这些密钥。Amazon Encryption SDK 是一个客户端加密库,可帮助您加密和解密通用数据。

CustomEmailSender

Amazon Cognito 调用此触发器向用户发送电子邮件通知。

CustomSMSSender

Amazon Cognito 调用此触发器向用户发送 SMS 通知。

加密概念

Amazon Cognito 不会在发送给自定义发件人触发器的事件中以明文形式发送用户的代码。Lambda 函数必须解密事件中的代码。以下概念是加密架构,您的函数必须使用该架构来获取可以传递给用户的代码。

Amazon KMS

Amazon KMS 是用于创建和控制 Amazon KMS 钥匙的托管服务。这些密钥加密您的数据。有关更多信息,请参阅什么是 Amazon Key Management Service?

KMS 密钥

KMS 密钥是加密密钥的逻辑表示形式。KMS 密钥包含元数据,如密钥 ID、创建日期、描述和密钥状态。KMS 密钥还包含用于加密和解密数据的密钥材料。有关更多信息,请参阅 Amazon KMS 密钥

对称 KMS 密钥

对称 KMS 密钥是一个 256 位加密密钥,它不会退出 Amazon KMS 而不加密。要使用对称 KMS 密钥,您必须调用 Amazon KMS。Amazon Cognito 使用对称密钥。加密和解密使用同一密钥。有关更多信息,请参阅对称 KMS 密钥

有关自定义发件人 Lambda 触发器的需知信息

  • 要配置用户池以使用这些 Lambda 触发器,您可以使用 Amazon CLI 或开发工具包。无法从 Amazon Cognito 控制台进行这些配置。

    UpdateUserPool 操作可设置 Lambda 配置。对此操作的请求需要包含用户池的所有参数 您要更改的参数。如果您没有提供所有相关参数,Amazon Cognito 会将任何缺失参数的值设置为其原定设置。如以下 Amazon CLI 示例所示,包括您想要添加到或保留在用户池中的所有 Lambda 函数的条目。有关更多信息,请参阅更新用户池和应用程序客户端配置

    #Send this parameter in an 'aws cognito-idp update-user-pool' CLI command, including any existing #user pool configurations. This snippet also includes a pre sign-up trigger for syntax reference. The pre sign-up trigger #doesn't have a role in custom sender triggers. --lambda-config "PreSignUp=lambda-arn, \ CustomSMSSender={LambdaVersion=V1_0,LambdaArn=lambda-arn}, \ CustomEmailSender={LambdaVersion=V1_0,LambdaArn=lambda-arn}, \ KMSKeyID=key-id"

    对于使用 UpdateUserPool 的 JSON 正文的请求,以下 LambdaConfig 代码段可分配自定义的短信和电子邮件发件人函数。

    "LambdaConfig": { "KMSKeyID": "arn:aws:kms:us-east-1:111122223333:key/a6c4f8e2-0c45-47db-925f-87854bc9e357", "CustomEmailSender": { "LambdaArn": "arn:aws:lambda:us-east-1:111122223333:function:MyFunction", "LambdaVersion": "V1_0" }, "CustomSMSSender": { "LambdaArn": "arn:aws:lambda:us-east-1:111122223333:function:MyFunction", "LambdaVersion": "V1_0" }
  • 要使用 update-user-pool Amazon CLI 命令删除自定义发件人 Lambda 触发器,请在 --lambda-config 中省略 CustomSMSSenderCustomEmailSender 参数,并包括要与用户池结合使用的所有其他触发器。

    要使用 UpdateUserPool API 请求删除自定义发件人 Lambda 触发器,请在包含其余用户池配置的请求正文中省略 CustomSMSSenderCustomEmailSender 参数。

  • Amazon Cognito HTML 会转义用户临时密码中的保留字符,例如 <&lt;)和 &gt;>)等。这些字符可能出现在 Amazon Cognito 发送到您的自定义电子邮件发件人函数的临时密码中,但不会出现在临时验证码中。要发送临时密码,您的 Lambda 函数在解密密码之后必须取消对这些字符的转义,然后再将消息发送给您的用户。

激活自定义发件人 Lambda 触发器

要使用自定义逻辑为您的用户池发送短信或电子邮件消息,请设置自定义发件人触发器。以下步骤会将自定义短信触发器和/或自定义电子邮件触发器分配给您的用户池。添加自定义发件人触发器后,Amazon Cognito 始终向您的 Lambda 函数发送用户属性(包括电话号码)和一次性代码,而不是采用发送短信或电子邮件消息的默认行为。

  1. 在 Amazon Key Management Service(Amazon KMS)中创建对称加密密钥。Amazon Cognito 生成密钥(临时密码、验证码、身份验证一次性密码和确认码),然后使用此 KMS 密钥通过 Amazon Encryption SDK 对这些密钥进行加密。然后,您可以在 Lambda 函数中使用 Amazon Encryption SDK 来解密这些密钥并以明文形式将其发送给用户。

  2. 创建或更新您的用户池的 IAM 主体会针对 Amazon Cognito 用于加密代码的 KMS 密钥创建一次性授权。请为该主体授予对您的 KMS 密钥的 CreateGrant 权限。要使本示例中的 KMS 密钥策略生效,更新用户池的管理员必须以 IAM 角色 arn:aws:iam::111222333444:role/my-example-administrator-role 的代入角色会话身份登录。

    请将以下基于资源的策略(已针对您的环境进行修改)应用于您的 KMS 密钥。

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/my-example-administrator-role" }, "Action": "kms:CreateGrant", "Resource": "arn:aws:kms:us-west-2:111122223333:key/1example-2222-3333-4444-999example", "Condition": { "StringEquals": { "kms:EncryptionContext:userpool-id": "us-west-2_EXAMPLE" } } }, { "Sid": "Allow Lambda to decrypt", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:role/my-lambda-function-role" }, "Action": "kms:Decrypt", "Resource": "*" }] }
  3. 为自定义发件人触发器创建 Lambda 函数。Amazon Cognito 使用 Amazon Encryption SDK 加密密钥、临时密码和授权用户 API 请求的代码。

    1. 分配一个 Lambda 执行角色,该角色至少具有针对您的 KMS 密钥的 kms:Decrypt 权限。

    2. 编写 Lambda 函数代码以发送消息。您函数的输入事件将包含一个密钥。在您的函数中,使用 Amazon Encryption SDK 解密该密钥并处理任何相关的元数据。然后将代码、您自己的自定义消息和目标电话号码发送到传送消息的自定义 API。

    3. 将 Amazon Encryption SDK 添加到 Lambda 函数。有关更多信息,请参阅 Amazon Encryption SDK 编程语言。要更新 Lambda 包,请完成以下步骤:

      1. 在 Amazon Web Services 管理控制台 中将您的 Lambda 函数作为.zip 文件导出。

      2. 打开您的函数并添加 Amazon Encryption SDK。有关更多信息和下载链接,请参阅 Amazon Encryption SDK Developer Guide(《Crypto SDK 开发人员指南》)中的 Amazon Encryption SDK 编程语言

      3. 压缩您的函数及 SDK 依赖项,然后将函数上传到 Lambda。有关更多信息,请参阅《Amazon Lambda 开发人员指南》中的将 Lambda 函数部署为 .zip 文件归档

  4. 授予 Amazon Cognito 服务主体 cognito-idp.amazonaws.com 访问权限,以调用 Lambda 函数。

    以下 Amazon CLI 命令授予 Amazon Cognito 调用 Lambda 函数的权限。

    aws lambda add-permission --function-name lambda_arn --statement-id "CognitoLambdaInvokeAccess" --action lambda:InvokeFunction --principal cognito-idp.amazonaws.com
  5. 生成一个包含 LambdaConfig 参数的 UpdateUserPool API 请求,以添加自定义发件人 Lambda 触发器。此类触发器无法通过 Amazon Cognito 控制台添加。自定义发件人触发器要求 LambdaConfig 参数中必须包含 KMSKeyID 以及 CustomSMSSenderCustomEmailSender(或两者同时包含)。