【问题标题】:Getting "AccessDenied: Access Denied" inside lambda when getting an object from s3从 s3 获取对象时,在 lambda 中获取“AccessDenied:Access Denied”
【发布时间】:2022-02-11 22:00:14
【问题描述】:

更新 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 不是很精通,所以如果这感觉不完整,请耐心等待。我还可以检查什么/在哪里查看为什么会发生这种情况?提前致谢。

【问题讨论】:

  • Lambda 函数不使用 IAM 用户,而是使用 IAM 角色。你能分享角色的权限策略吗?看起来是这个问题
  • @Caldazar 我已更新问题以包含政策。在此过程中,我还注意到自定义策略授予不同 s3 存储桶的 s3 访问权限,而不是我尝试访问的存储桶,所以也许就是这样。我会检查并提供反馈。如果还有其他关于政策的内容,请告诉我。
  • @Caldazar 将存储桶添加到策略并没有解决问题。你认为我还能尝试/检查什么?我再次更新了问题,以展示我是如何尝试更改政策的。

标签: amazon-web-services amazon-s3 aws-lambda amazon-cloudfront aws-lambda-edge


【解决方案1】:

问题在于您的政策。该策略允许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"
    }

【讨论】:

猜你喜欢
  • 2023-01-03
  • 2016-07-14
  • 2023-03-25
  • 2019-07-24
  • 2015-11-19
  • 2017-06-27
  • 1970-01-01
  • 1970-01-01
  • 2018-01-26
相关资源
最近更新 更多