从 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 个策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "xray:PutTraceSegments",
                "xray:PutTelemetryRecords",
                "xray:GetSamplingRules",
                "xray:GetSamplingTargets",
                "xray:GetSamplingStatisticSummaries"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
{
    "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"
    }