【发布时间】:2017-12-31 14:42:32
【问题描述】:
我有一个 AWS Lambda 函数,它通过其 URL(即 https://s3-eu-west-1.amazonaws.com/bucketname/key)访问 S3 资源。
我在 S3 存储桶上添加了一个存储桶策略,允许我的 Lambda 函数访问 S3 存储桶(通过 Lambda 函数 IAM 角色)。此存储桶策略如下所示:
{
"Version": "2012-10-17",
"Id": "Access control to S3 bucket",
"Statement": [
{
"Sid": "Allow Get and List Requests from IAM Role",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123412341234:role/role-name“
},
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::bucket-name”,
"arn:aws:s3:::bucket-name/*"
]
}
]
}
当 Lambda 函数由触发器“自动”激活时,这一切正常。但是当我手动(通过 AWS 控制台)测试 Lambda 函数时,我收到 403 错误。
如果我随后将 S3 存储桶策略中的 Principal 更改为“*”,则 403 异常得到解决。
我的猜测是手动触发 Lambda 函数时使用了不同的 Principal,但我不知道这可能是什么。我尝试添加一个新策略,授予我的规范用户访问权限,但这不起作用。
有什么建议吗?
【问题讨论】:
-
您为什么要通过其 URL 访问 Amazon S3 对象?像 s3-eu-west-1.amazonaws.com/bucketname/key 这样的 URL 不发送任何标识,因此它是一个匿名请求。如果对象不是公开的,它应该总是收到 403 错误。最好通过经过身份验证的 API 调用或使用 S3 预签名 URL 来访问对象。
-
我没有意识到我需要使用 AWS S3 控制台中的“下载”或“下载为”按钮,而不是使用属性页面底部的 URL。一直在追403错误鬼。
-
@JohnRotenstein 我的用例是我使用 Nodemailer + SES 发送带有 S3 对象作为附件的电子邮件。也许 S3 预签名 URL 可能适合这里?
-
因此,您需要授予 Lambda 函数对 S3 对象的访问权限,以便它可以将其附加到电子邮件中。是的,您可以将签名 URL 传递给特定 S3 对象的 Lambda 函数,或者您可以授予 Lambda 函数对 S3 的访问权限,以便始终能够访问该对象。除非您对安全性特别敏感,否则第二个更合乎逻辑。您能否显示生成 403 错误的代码——它是对 S3 进行 API 调用,还是尝试通过公共 URL 检索对象?
-
@MattD -- 这完全取决于如何获取对象。如果访问是通过使用 AWS JavaScript 开发工具包的 API 调用,则将使用角色的凭证。但是,如果对象是通过一个没有传递凭据的 URL 获取的,那么访问将被拒绝。
标签: amazon-web-services amazon-s3 aws-lambda amazon-iam