我正在使用通过Google验证的Cognito凭据提供程序直接从Android调用lambda。通过使用该凭证提供程序获得的角色允许我调用lambda。我可以在我的CloudWatch日志中看到lambda确实在传递给lambda处理程序的上下文变量中接收到用户的Cognito身份。 lambda假定一个角色使用此标识变量来限制lambda对Cognito标识变量命名的特定S3用户文件夹的访问。
{
"Effect":"Allow",
"Action":[
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:DeleteObject"
],
"Resource":[
"arn:aws:s3:::BUCKET_NAME/users/${cognito-identity.amazonaws.com:sub}/",
"arn:aws:s3:::BUCKET_NAME/users/${cognito-identity.amazonaws.com:sub}/*"
]
},
{
"Effect":"Allow",
"Action":[
"s3:ListBucket",
"s3:ListObjects"
],
"Resource":[
"arn:aws:s3:::BUCKET_NAME"
],
"Condition":{
"StringLike":{
"s3:prefix":[
"users/${cognito-identity.amazonaws.com:sub}/",
"users/${cognito-identity.amazonaws.com:sub}/*"
]
}
}
}
但是,lambda似乎没有继承这些环境变量特定的限制。为了使lambda代码有效,我需要放松这样的约束:
{
"Effect":"Allow",
"Action":[
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:DeleteObject"
],
"Resource":[
"arn:aws:s3:::BUCKET_NAME/users/*"
]
},
{
"Effect":"Allow",
"Action":[
"s3:ListBucket",
"s3:ListObjects"
],
"Resource":[
"arn:aws:s3:::BUCKET_NAME"
],
"Condition":{
"StringLike":{
"s3:prefix":[
"users/*"
]
}
}
}
我认为这与承担角色的lambda服务有关。如果我直接将该角色用于S3客户端,则限制似乎有效。客户端可以访问自己的文件夹,但没有其他人的文件夹。但是,如果lambda承担角色它不起作用,我必须放松策略约束。我做错了什么或误解了什么?
答案 0 :(得分:0)
好的,我想我想出来了。如我错了请纠正我。看起来我需要两个角色。 lambda将承担的一个角色是做它需要做的任何事情。该特定角色不受任何Cognito登录凭据的限制,因为当Lambda服务承担此角色时,它无权访问这些凭据。安全性来自SECOND角色,该角色具有INVOKE lambda的权限,但不像Lambda角色那样具有对所有S3的完全访问权限。该角色可以而且应该要求身份验证。实际效果是你可以要求身份验证来调用lambda,但是你必须小心lambda代码本身才能访问你不应该访问的任何资源。 Cognito凭据被传递到lambda函数(因为您使用经过身份验证的角色调用它),因此您可以从上下文中了解您应该使用的资源,即S3中的用户文件夹。