无法从 S3 存储桶 'getObject' - 策略无效

Cannot 'getObject' from S3 bucket - policy not working

我已经为此花费了 10 多个小时(我知道我知道),但就是无法深入了解它。


更新 - 请参阅 QN 的底部


场景

我有一个应用程序允许用户将对象上传到 S3,然后在以后他们喜欢的时候下载它。

使用下面的策略,上传工作正常,getObject 调用,但是没有。

IAM 用户策略

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}

我在上面也尝试了一些其他更细粒度的策略,但是 none 有效,因此,为了让它起作用,我正在尝试设置一个用户策略来授予 root对 AWS 的级别访问,目的是从那里对其进行微调。

存储桶策略

我认为这不需要任何存储桶策略,但是,对于它的价值,我没有尝试任何策略以及以下策略:

{
    "Version": "2012-10-17",
    "Id": "AWSGeneratedPolicyId",
    "Statement": [
        {
            "Sid": "RandomSidGeneratedHere",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::305492142848:user/username-this-line-copy-pasted-from-AWS-IAM-console"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::bucketname",
                "arn:aws:s3:::bucketname/*"
            ]
        }
    ]
}

函数调用 getObject:

const params = {
        Bucket: 'bucketname',
        Key: 'objectkey',
    };
    s3.getObject(params, function(err, data) {
        if (err) {
            console.log(err.message);
        } else {
            console.log(data);
        }
    });

结果和错误消息

<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>FC1698B03B31AF06</RequestId>
  <HostId>
    ZDDPr+WHCAnoAY/FyGTZA3iv8+L9R0r5CYGI5Owf/DOsItmsU5BSEtD8qXAZc4UHSgSqv2zneH4=
  </HostId>
</Error>

疑难解答:

我知道凭据是正确的,因为上传工作正常 我知道上面的 'test' 硬编码函数是正确的(就存储桶名称和密钥而言),因为如果我将存储桶更改为 'public' 进行读取,那么函数调用 getObject 工作正常

以上暗示相关 IAM 用户没有 getObject 的权限 - 但根据应用的用户策略,还需要什么权限??

非常感谢任何建议(注意 - 我浏览了论坛并看到了类似的问题,但 none 的答案似乎对我有用)

更新

一时兴起,我更改了函数来执行此操作:

s3.listBuckets({}, function(err, data) {
    if (err) console.log(err, err.stack);
    console.log(data);
}

并且我没有列出所有预期的存储桶,而是从另一个帐户获取存储桶列表。尽管下面是顶部的代码,但这种情况仍在发生:

const AWS = require('aws-sdk');

AWS.config = new AWS.Config();
AWS.config.accessKeyId = process.env.AWS_KEY;
AWS.config.secretAccessKey = process.env.AWS_SECRET;
AWS.config.region = 'ap-southeast-2';

const s3 = new AWS.S3();

这种奇怪现象现在是有道理的 - 列出的存储桶是完全不同的 AWS 帐户上的存储桶(我在试验 serverless.com 框架时创建的帐户)。

假设

本地服务器的配置以某种方式固定,代码中设置的配置属性没有影响。

我可以通过将完全相同的代码部署到它按预期工作的实际服务器(即 getObject 调用工作正常)来确认这种情况

修改后的问题:

如何清除 'cache' 或终端中保留这些值的任何内容?这是 iTerm/serverless.com 的错误吗(如果是这样我可以采取必要的步骤...)。如果这不是错误而是预期的行为,那么将来应该如何避免这种情况?

我已经尝试过此政策并成功了。

尝试在我的存储桶策略下使用 *(只是为了丢弃)访问所有 AWS IAM 帐户,另一件事,你为什么使用过期 属性?无论如何尝试删除该行。

{
    "Version": "2012-10-17",
    "Id": "AWSGeneratedPolicyId",
    "Statement": [
        {
            "Sid": "RandomSidGeneratedHere",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucketname/*"
        }
    ]
}

此外,上传图片时,请检查您是否分配了 ACL 属性:

S3.putObject({
            Bucket: process.env.bucket,
            Body: imageContent.body,
            Key: `${key}`,
            ACL:'public-read'
        })

编码愉快!

好的,根据更新后的问题 - 以及来自 listObjects 函数调用的线索,我发现在服务器运行时,AWS 配置忽略了我的凭据以支持存储在路径中的凭据: ~/.aws/credentials.

解决方案:

删除提到的 credentials 文件,一切正常...