从 s3 获取对象时在 lambda 中获取 "AccessDenied: Access Denied"
Getting "AccessDenied: Access Denied" inside lambda when getting an object from s3
更新 2
我尝试更改我们的自定义策略以允许访问出现 AccessDenied
错误的特定存储桶,但没有成功。假设 bucket1
是 lambda 通常访问的桶,而 bucket2
是在 lambda 访问它时抛出 AccessDenied
的桶。我已经将 Resource
块从
更改为
{
...
{
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::us-east-1-bucket1/*",
"Effect": "Allow"
}
...
至
{
...
{
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::us-east-1-bucket1/*",
"arn:aws:s3:::us-east-1-bucket2/*"
],
"Effect": "Allow"
}
...
我仍然遇到 AccessDenied
错误。
更新
根据@Caldazar 关于 IAM 用户与角色的评论,lambda 的执行角色有 3 个策略:
- AWS 托管
arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess
,特别是:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:GetSamplingRules",
"xray:GetSamplingTargets",
"xray:GetSamplingStatisticSummaries"
],
"Resource": [
"*"
]
}
]
}
- AWS 托管
arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
,特别是:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
- 我们的自定义策略,特别是:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:*"
],
"Resource": "arn:aws:logs:us-east-1:*:log-group:/aws/lambda/*:*:*",
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::us-east-1-bucket1/*",
"Effect": "Allow"
}
]
}
在 lambda@edge 中,我有一个 origin-response
响应 lambda,它试图从 s3 中拉出一个对象以用作响应。但是,当我尝试使用特定前缀列出存储桶的内容时,出现此 AccessDenied
错误。这是我的代码:
const getVidS3 = (s3, bucketName, fileName) =>
new Promise((res, rej) => {
const start = Date.now();
s3.listObjects(
{
Bucket: bucketName,
Delimiter: '/',
Prefix: `${fileName}/`,
MaxKeys: 1,
},
function (err, data) {
console.log(
'================ milliseconds to list objects:',
Date.now() - start
);
if (err) return rej(err);
if (!Array.isArray(data.Contents) || data.Contents.length < 1) {
return rej('original raw video not found');
}
console.log('============= s3 objects:', data);
const rawVidFileKey = data.Contents[0].Key;
s3.getObject(
{
Bucket: bucketName,
Key: rawVidFileKey,
},
(err, data) => {
console.log(
'================ milliseconds to get video object:',
Date.now() - start
);
if (err) {
return rej(err);
}
const contentType = data.ContentType;
const video = data.Body;
console.log('=============== S3 video data', data);
return res({ video, contentType });
}
);
}
);
});
错误来自 listObjects
。我已经检查了 this set of suggestions 但我不确定我采取了正确的步骤,因为我使用了我用来访问仪表板的 IAM 用户,它可能比 lambda 使用的用户具有更高的权限。更重要的是,我使用我的管理员凭据在本地重新创建了这个 getVidS3
函数并且它有效,所以我认为我需要帮助来确定如何为 lambda 提供适当的权限。我没有创建系统,我也不是很精通 aws,所以如果感觉不完整,请耐心等待。 What/where 否则我可以查看为什么会这样吗?提前致谢。
问题出在您的保单上。该策略允许 GET
个对象,但不允许 List
个对象。您缺少对存储桶本身的 ListBucket
操作。
你需要改变这个:
{
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::us-east-1-bucket1/*",
"Effect": "Allow"
}
为此:
{
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::us-east-1-bucket1/*",
"arn:aws:s3:::us-east-1-bucket1"
]
"Effect": "Allow"
}
更新 2
我尝试更改我们的自定义策略以允许访问出现 AccessDenied
错误的特定存储桶,但没有成功。假设 bucket1
是 lambda 通常访问的桶,而 bucket2
是在 lambda 访问它时抛出 AccessDenied
的桶。我已经将 Resource
块从
{
...
{
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::us-east-1-bucket1/*",
"Effect": "Allow"
}
...
至
{
...
{
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::us-east-1-bucket1/*",
"arn:aws:s3:::us-east-1-bucket2/*"
],
"Effect": "Allow"
}
...
我仍然遇到 AccessDenied
错误。
更新
根据@Caldazar 关于 IAM 用户与角色的评论,lambda 的执行角色有 3 个策略:
- AWS 托管
arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess
,特别是:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:GetSamplingRules",
"xray:GetSamplingTargets",
"xray:GetSamplingStatisticSummaries"
],
"Resource": [
"*"
]
}
]
}
- AWS 托管
arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
,特别是:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
- 我们的自定义策略,特别是:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:*"
],
"Resource": "arn:aws:logs:us-east-1:*:log-group:/aws/lambda/*:*:*",
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::us-east-1-bucket1/*",
"Effect": "Allow"
}
]
}
在 lambda@edge 中,我有一个 origin-response
响应 lambda,它试图从 s3 中拉出一个对象以用作响应。但是,当我尝试使用特定前缀列出存储桶的内容时,出现此 AccessDenied
错误。这是我的代码:
const getVidS3 = (s3, bucketName, fileName) =>
new Promise((res, rej) => {
const start = Date.now();
s3.listObjects(
{
Bucket: bucketName,
Delimiter: '/',
Prefix: `${fileName}/`,
MaxKeys: 1,
},
function (err, data) {
console.log(
'================ milliseconds to list objects:',
Date.now() - start
);
if (err) return rej(err);
if (!Array.isArray(data.Contents) || data.Contents.length < 1) {
return rej('original raw video not found');
}
console.log('============= s3 objects:', data);
const rawVidFileKey = data.Contents[0].Key;
s3.getObject(
{
Bucket: bucketName,
Key: rawVidFileKey,
},
(err, data) => {
console.log(
'================ milliseconds to get video object:',
Date.now() - start
);
if (err) {
return rej(err);
}
const contentType = data.ContentType;
const video = data.Body;
console.log('=============== S3 video data', data);
return res({ video, contentType });
}
);
}
);
});
错误来自 listObjects
。我已经检查了 this set of suggestions 但我不确定我采取了正确的步骤,因为我使用了我用来访问仪表板的 IAM 用户,它可能比 lambda 使用的用户具有更高的权限。更重要的是,我使用我的管理员凭据在本地重新创建了这个 getVidS3
函数并且它有效,所以我认为我需要帮助来确定如何为 lambda 提供适当的权限。我没有创建系统,我也不是很精通 aws,所以如果感觉不完整,请耐心等待。 What/where 否则我可以查看为什么会这样吗?提前致谢。
问题出在您的保单上。该策略允许 GET
个对象,但不允许 List
个对象。您缺少对存储桶本身的 ListBucket
操作。
你需要改变这个:
{
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::us-east-1-bucket1/*",
"Effect": "Allow"
}
为此:
{
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::us-east-1-bucket1/*",
"arn:aws:s3:::us-east-1-bucket1"
]
"Effect": "Allow"
}