使用 S3 的 Amazon Cloudfront。拒绝访问

Jor*_*ams 126 permissions amazon-s3 amazon-cloudfront amazon-web-services

我们正在尝试通过 Cloudfront 分发 S3 存储桶,但由于某种原因,唯一的响应是一个 AccessDenied XML 文档,如下所示:

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>89F25EB47DDA64D5</RequestId>
    <HostId>Z2xAduhEswbdBqTB/cgCggm/jVG24dPZjy1GScs9ak0w95rF4I0SnDnJrUKHHQC</HostId>
</Error>
Run Code Online (Sandbox Code Playgroud)

这是我们正在使用的设置:

分发设置 原点设置

这是存储桶的策略

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity *********"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::x***-logos/*"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

Kou*_*sha 141

如果您要访问 CloudFront 分配的根,则需要设置默认根对象:http : //docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html

要使用 CloudFront 控制台指定默认根对象:

  • 登录 AWS 管理控制台并通过https://console.aws.amazon.com/cloudfront/打开 Amazon CloudFront 控制台。

  • 在顶部窗格的分发列表中,选择要更新的分发。

  • 在“分发详细信息”窗格中的“常规”选项卡上,单击“编辑”

  • 在“编辑分发”对话框的“默认根对象”字段中,输入默认根对象的文件名。

    仅输入对象名称,例如,index.html。不要在对象名称前添加 /。

  • 要保存更改,请单击是,编辑

  • 就我而言,此设置并未解决问题。我仍然收到拒绝访问错误 (8认同)
  • 天哪,为什么这与围绕该主题的任何 aws 知识答案无关!谢谢 (2认同)

Mir*_*lav 81

我刚刚遇到了同样的问题,虽然 Kousha 的答案确实解决了根路径中index.html的问题,但我的问题也出在子目录上,因为我将那些与index.html结合使用以获得“漂亮的 url”(例如.com/something/ 而不是“丑陋的”example.com/something.html)

部分原因也是亚马逊的错,因为当您设置 CloudFront 分配时,它会为您提供 S3 存储桶供您选择,但如果您选择其中之一,它将使用存储桶 URL 而不是静态网站托管 URL 作为后端。

所以要解决这个问题:

  • 为存储桶启用静态网站托管
  • 适当地设置Index(可能还有Error)文档
  • 复制端点URL - 您可以在上述设置旁边找到它 - 它应该类似于:<bucket.name>.s3-website-<aws-region>.amazonaws.com
  • 使用该 URL 作为您的 CloudFront 分发源。(这也将使 CF默认根对象设置变得不必要,但无论如何设置它也无妨)


小智 15

我遇到了与@Cezz 相同的问题,尽管该解决方案在我的情况下不起作用。

一旦为存储桶启用静态网站托管,这意味着用户可以通过 Cloudfront URL 或 S3 URL 访问内容,这并不总是可取的。例如,在我的例子中,Cloudfront 发行版启用了 SSL,用户应该无法通过非 SSL 连接访问它。

我找到的解决方案是:

  • 在 S3 存储桶上禁用静态网站托管
  • 将 Cloudfront 分发源保留为 S3 ID
  • 将“限制存储桶访问”设置为“是”(为方便起见,允许 CloudFront 自动更新存储桶策略)
  • 在“错误页面”上,创建自定义响应,并将错误代码“403:禁止”映射到所需的响应页面即/index.html,响应代码为200

请注意,在我的情况下,我正在提供一个单页 javascript 应用程序,其中所有路径都由 index.html 解析。如果您的路径解析到 S3 存储桶中的不同对象,这将不起作用。


小智 8

就我而言,我在 S3 存储桶中使用了多个具有“路径模式”行为的源以及一个源路径:

错误的设置:

CloudFront 行为: /images/*->My-S3-origin

My-S3-origin: 来源路径: /images

S3 文件:/images/my-image.jpg

GET 请求:/images/my-image.jpg -> 403

发生的事情是整个 CloudFront GET 请求被发送到 origin:/image/my-image.jpg前缀为 Origin Path: /images,因此进入 S3 的请求看起来/images/images/my-image.jpg不存在。

解决方案

删除原点路径。

这允许我使用原始访问身份和存储桶权限以及受限制的单个文件权限访问存储桶。