67

我正在使用 S3 存储一些关键业务文档。我希望存储桶在尝试访问存储桶中不存在的对象时返回 404 状态代码。

但是,我发现它一直在向我返回“403

这是使用 S3 网站 url 的会话示例。

> GET /foobar.txt HTTP/1.1
> User-Agent: curl/7.21.6 (x86_64-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3
> Host: <bucketname>.s3-website-us-east-1.amazonaws.com
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
< Last-Modified: Mon, 09 Sep 2013 19:10:28 GMT
< ETag: "14e13b81b3ce5b129d1f206b3e514885"
< x-amz-error-code: AccessDenied
< x-amz-error-message: Access Denied
< x-amz-request-id: <snip>
< x-amz-id-2: <snip>
< Content-Type: text/html
< Content-Length: 11
< Date: Thu, 26 Sep 2013 20:01:45 GMT
< Server: AmazonS3
< 
Not found!

请注意,“未找到!” 字符串来自启用 S3 网站托管时在存储桶属性上设置的错误文档。

我也尝试过直接使用存储桶 url 访问

http://.s3.amazonaws.com/

并且返回相同,除了我得到一个 XML 文档而不是错误文档

我该如何解决这个问题?

4

5 回答 5

95

当用户无权列出存储桶内容时,S3 返回 403 而不是 404。

如果您查询一个对象并收到 404,那么您就知道该对象不存在。如果您无权列出存储桶内容,则这是您不应该知道的信息,因此 S3 不会告诉您它不存在,而是告诉您您正在尝试做您不允许做的事情. 当您收到 403 而不是 404 时,您无法知道您请求的对象不存在。它可能不存在,或者它可能存在,而您只是无权访问它。您无法确切知道,因此不会绕过任何安全措施。

我相信任何有权列出存储桶内容的人都会得到 404 而不是 403。

于 2013-09-26T20:25:14.547 回答
36

确切的要求似乎是您的用户ListBucket对您的特定存储桶具有权限,并且 ARN 的格式正好是arn:aws:s3:::your_bucket_name

我还需要在我的策略中添加一个全新的声明,因为其他权限(例如GetObject,仍然需要 ARN 以/*或其他合适的通配符结尾)。

{
  "Action": [
    "s3:ListBucket"
  ],
  "Sid": "StmtNNNNNNNNNNNNNNNwholebucket",
  "Resource": [
    "arn:aws:s3:::your_bucket_name"
  ],
  "Effect": "Allow"
},

总而言之,对我来说重要的一点是,如果 ARN 不是arn:aws:s3:::your_bucket_name/*ListBucket 的形式,或者您仍然会得到 403 而不是 404。

于 2013-11-06T09:59:09.680 回答
19

不确定你是否正在寻找这个。将您的对象公开给所有人可以解决 404 问题。但是,我认为这是完成它的理想方式。

AWS Cloudfront 提供了一项称为原始访问身份 ( OAI) 的功能。这里详细介绍了它的工作原理。

简而言之,将 OAI 与您在 Cloudfront 中的 Origin 关联并更新存储桶策略以允许 OAIGetObjectListBucket所示

{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "AllowOAIRead",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity your_OAI_ID"
        ]
      },
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::your_bucket_name/*",
        "arn:aws:s3:::your_bucket_name"
      ]
    }
  ]
}
于 2019-08-25T19:19:58.307 回答
11

我需要像这样扩展政策:

 "Action": [
   "s3:Get*",
   "s3:List*"
 ],
 "Resource": [
   "arn:aws:s3:::bucket_name",
   "arn:aws:s3::: bucket_name/*"
 ],

bucket_name需要,因为没有它,您不会因为丢失的对象而得到 404,但总是bucket_name/*需要 403 才能实际访问存储桶中的内容。

于 2019-04-01T13:27:34.177 回答
7

确保在您的权限Everyone中有View Permissions.

您可能还想添加存储桶策略:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your_bucket_name/*"
        }
    ]
}
于 2013-09-26T20:24:51.293 回答