如何允许 API Gateway REST API 用户通过 Amazon Cognito 用户池组中的执行角色运行 Lambda 函数?
上次更新时间:2021 年 10 月 7 日
使用 AWS Lambda 代理集成的 Amazon API Gateway REST API 具有 Amazon Cognito 用户池身份验证。如何让我的 API 用户使用与其用户用户池组关联的 AWS Identity and Access Management (IAM) 角色(而不是使用默认 Lambda 执行角色)运行 Lambda 函数?
解决方法
注意:除了 Amazon Cognito 用户池之外,您还可以配置身份池以授权访问您的 API。有关更多信息,请参阅基于角色的访问控制。
在设置用户以使用他们的 Amazon Cognito 角色运行 Lambda 之前,请确保您已进行如下设置:
- Amazon Cognito 用户池和具有关联 IAM 角色的用户池组。
- 使用 Amazon Cognito 用户身份验证的客户端应用程序。
- 使用 Lambda 代理集成的 API Gateway REST API。
- 如果您在运行 AWS Command Line Interface (AWS CLI) 命令时收到错误,请确保您运行的是最新版本的 AWS CLI。
要允许用户使用他们的 Amazon Cognito 权限运行 Lambda,请按照以下步骤操作:
- 使用 API Gateway 控制台 以授权方的身份建立您的 Amazon Cognito 用户池。然后,将 Amazon Cognito 用户池分配为您的 API 方法的授权方。有关说明,请参阅将 REST API 与 Amazon Cognito 用户池集成。
- 打开 AWS Lambda 控制台。
- 选择已配置为 API 的代理资源的 Lambda 函数。
- 配置 Lambda 函数,并添加以下代码段。此代码段会从事件详细信息中获取 Amazon Cognito 角色,然后代入该角色。
注意:要运行此代码段,您的 Lambda IAM 角色必须拥有访问 Amazon CloudWatch Logs 及 AssumeRole API 调用的权限,才能运行 assume_role 命令。
import boto3
client = boto3.client('sts')
def lambda_handler(event, context):
role=event['requestContext']['authorizer']['claims']['cognito:roles']
response = client.assume_role(
RoleArn=role,
RoleSessionName='APIrole'
)
print(response)
response2api = {"statusCode": 200,"headers": { },"body": "Success"}
return response2api
一个用户可以属于多个 Amazon Cognito 用户池组,而每个组可以具有不同的 IAM 角色。如果某个用户属于两个或更多组,cognito:roles 陈述会返回角色列表。用户 ID 令牌中的 cognito:preferred_role 陈述会继承具有最高优先级(优先级值最小)的组的 IAM 角色。有关更多信息,请参阅基于角色的访问控制。
要获取 cognito:preferred_role,请使用以下代码段:
role = event['requestContext']['authorizer']['claims']['cognito:preferred_role']
要验证用户是否可以使用其 Amazon Cognito 角色运行 Lambda,请按照以下步骤操作:
- 打开您的客户端应用程序,以 Amazon Cognito 用户池中用户的身份登录。
- 使用登录后收到的 ID 令牌调用您的 API。
注意:请确保使用返回令牌中的 id_token 值。 - 验证您是否可以访问 Amazon Cognito 用户池角色中定义的相同资源。
- 可以选择查看 CloudWatch Logs,以验证 assume_role 命令是否成功。
注意:如果您使用 API Gateway Lambda 授权方而非用户池授权方来授权访问您的 API,请确保使用经过授权方验证的用户池令牌。在您承担令牌的角色之前,必须对令牌进行验证。