如何获取调用 AWS Lambda 函数的用户(由 AWS Cognito 登录)的身份 ID?我是否必须使用 Lambda 函数上的开发工具包来获取身份 ID?
7 回答
在 lambda 函数内的 AWS javascript SDK 中,只需使用 context.identity.cognitoIdentityId 它对我有用
如果您通过 API Gateway,您可以将 cognito id(以及用户 arn 和其他有用信息)传递给 Lambda。这为我解决了这个问题。
如果其他人偶然发现这一点,我认为这会对您有很大帮助。
请注意,这仅适用于您使用 Cognito 用户池授权器的情况。如果您想将 AWS_IAM 与 Cognito Identitys 一起使用,请查看我的 github 示例https://github.com/VictorioBerra/js-cognito-auth-example(向下阅读下面的编辑区域)
如果您选中了“使用 Lambda 代理集成”,那么您将无权访问请求模板映射。但是您可以在 lambda 函数中获取令牌内的声明:
exports.handler = (event, context, callback) => {
//create a response
const response = {
statusCode: 200,
body: JSON.stringify({
"user email": event.requestContext.authorizer.claims.email,
}),
};
callback(null, response);
};
编辑 - 有关使用 AWS_IAM 作为 APIG 授权方的更多信息
基本上,您需要使用 AWS_IAM 保护您的 APIG,并且您必须通过 Cognito 联合身份进行身份验证,该身份将使用用户池返回 sessionToken 示例。这就是使 AWS IAM 凭证临时的原因。现在您拥有了对 APIG 进行身份验证所需的一切。
要对此进行测试,请下载postman的桌面版本,输入您的 API URI(从阶段区域获取),然后在 Authorization 下填写 Sig4 签名所需的 5 个字段。您将看到 lambda 函数中的“event.identity”对象加载了user
对象等属性。
如果您想使用 APIG 自动生成的 SDK,它内置了一个工厂,该工厂为您获取accessKey
、secret
和token
并签署所有内容。与 aws-sdk 相同。您可以使用这三个项目初始化凭据,它会自动使用这些临时凭据为您签署所有请求。如果您想直接手动使用 window.fetch、request、curl(在此处插入 http 客户端)手动访问您的 API,您可以计算自己的 Sig4(注意它可能有点复杂或使用现代库为您完成。
另外作为记录,在做我的研究时,我注意到如果你不想使用 AWS_IAM 作为 APIG 授权者,并且你想使用“Cognito Identity Pool Authorizer”,这是 APIG 下拉列表中的一个新选项,你仍然可以获得如果您只是将从成功的 Cognito popl auth 获得的 JWT 作为 Authorization 标头传递给 APIG,那么 lambda 事件中的大量用户信息。在 JWT 内部有很多属性,您可以在池设置中自定义这些属性。
IMO 专业意见我认为使用 AWS_IAM 临时凭据授权者是首选。这样,您可以在 Cognito 身份(Facebook、Twitter、池等)中使用任意数量的不同 IdP
根据docs,看起来有关身份提供者的信息仅可用于通过 Mobile SDK 进行调用。
为了解决这个问题,一种选择是将身份 ID 作为事件的一部分手动传递给函数。假设您正在做类似的事情,AWS.config.credentials = new AWS.CognitoIdentityCredentials(...)
那么您应该能够通过AWS.config.credentials.identityId
(刷新凭据后)获取 ID。
编辑:身份验证的更好选择是让 Cognito/IAM 处理它,并假设用户可以成功调用 Lambda 函数,这意味着他们被允许。在这种情况下,要管理每个用户的验证,请查看whitelisting。
我的观察如下。
如果您使用签名的请求调用 API 网关,您实际上提供了可以通过(JS SDK)提取的访问密钥、秘密和会话令牌:
AWS.config.credentials = new AWS.CognitoIdentityCredentials(...)
AWS.config.credentials.get(..)
并假设您的 lambda 是通过 LAMBDA_PROXY 和 Authorizer AWS_IAM 从 API-Gateway 调用的。您只能通过以下方式访问 lambda 中的用户内容:
exports.create = function (event, context) {
secdata = event.requestContext.identity.cognitoAuthenticationProvider;
}
然后,除了其他东西之外,您还将获得 cognito UserPool User 的“子”。因此,如果您真的想了解更多有关用户的信息,您似乎需要通过 SDK 调用再次询问 AWS。
对于 Python Lambda,通过 Javascript AWS SDK / Cognito / Amplify 调用...
https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
context.identity.cognito_identity_id
它应该看起来像这样:
{aws region}:{ GUID }
假设您使用的是身份池,这将返回 Cognito 联合身份,可用于细粒度的访问控制。这比依赖包含身份 ID 的 Javascript 有效负载更安全。
Cognito 身份池身份验证角色需要具有 Lambda:InvokeFunction 策略,否则用户将无法首先调用该函数。
编辑:这在直接调用 Lambda 函数时有效,而不是通过 API 网关。
Edit2:允许 Cognito 用户调用 lambda,因为它在 IAM Cognito Auth 角色中明确设置。
我正在使用 Kotlin,而我的 Lambda 处理程序是
override fun handleRequest(event: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent
但event.requestContext
没有authorizer
。解决方案是将 build.gradle 中的依赖项从升级
com.amazonaws:aws-lambda-java-events:2.1.0
到com.amazonaws:aws-lambda-java-events:2.2.7
. 之后,我得到了如下用户名。
val claims = requestContext.authorizer["claims"] as Map<String, String>
println(claims["cognito:username"])
println(claims["email"])