AWS CloudFront 访问 S3 存储桶被拒绝

问题描述:

我正在尝试设置 CloudFront 以提供托管在我的 S3 存储桶中的静态文件.我已经安装了分发版,但是在尝试浏览 S3 存储桶中的 CSS (/CSS/stlyle.css) 文件时,我得到了 AccessDenied:

I am trying to setup CloudFront to serve static files hosted in my S3 bucket. I have setup distribution but I get AccessDenied when trying to browse to the CSS (/CSS/stlyle.css) file inside S3 bucket:

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>E193C9CDF4319589</RequestId>
    <HostId>
xbU85maj87/jukYihXnADjXoa4j2AMLFx7t08vtWZ9SRVmU1Ijq6ry2RDAh4G1IGPIeZG9IbFZg=
    </HostId>
</Error>

我已将 CloudFront 分配设置到我的 S3 存储桶并创建了新的 Origin Access Identity 策略,该策略已自动添加到 S3 存储桶:

I have set my CloudFront distribution to my S3 bucket and created new Origin Access Identity policy which was added automatically to the S3 bucket:

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E21XQ8NAGWMBQQ"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::myhost.com.cdn/*"
        }
    ]
}

我错过了什么吗?

我希望我在这个 S3 存储桶中的所有文件都通过 CloudFront 提供服务...

I want all my files in this S3 bucket be served via CloudFront...

*** 更新 ***

这个云前端指南说:

默认情况下,您的 Amazon S3 存储桶和其中的所有对象都是私有的——只有创建存储桶的 AWS 账户才有权读取或写入其中的对象.如果您想允许任何人使用 CloudFront URL 访问您的 Amazon S3 存储桶中的对象,您必须向这些对象授予公共读取权限.(这是使用 CloudFront 和 Amazon S3 时最常见的错误之一.您必须向 Amazon S3 存储桶中的每个对象明确授予权限.)

因此,基于此,我将 S3 存储桶内所有对象的新权限添加到 Everyone Read/Download.现在我可以访问文件了.

So based on this I have added new permissions to all objects inside S3 bucket to Everyone Read/Download. Now I can access files.

但是现在当我访问像 https://d3u61axijg36on.cloudfront.net/css/style.css 这样的文件时,这被重定向到 S3 URI 和 HTTP.如何禁用此功能?

But now when I access the file like https://d3u61axijg36on.cloudfront.net/css/style.css this is being redirected to S3 URI and HTTP. How do I disable this?

为了帮助解决您的问题,我通过以下方式重现了情况:

To assist with your question, I recreated the situation via:

  • 创建了一个没有存储桶策略的 Amazon S3 存储桶
  • 上传public.jpg并通过公开"公开
  • 上传了 private.jpg 并保密
  • 创建了一个 Amazon CloudFront 网络分配:
    • 源域名:从列表中选择了我的 S3 存储桶
    • 限制存储桶访问:
    • 源访问身份:创建新身份
    • 授予对存储桶的读取权限:是的,更新存储桶政策
    • Created an Amazon S3 bucket with no Bucket Policy
    • Uploaded public.jpg and make it public via "Make Public"
    • Uploaded private.jpg and kept it private
    • Created an Amazon CloudFront web distribution:
      • Origin Domain Name: Selected my S3 bucket from the list
      • Restrict Bucket Access: Yes
      • Origin Access Identity: Create a New Identity
      • Grant Read Permissions on Bucket: Yes, Update Bucket Policy

      我检查了存储桶,CloudFront 添加了与您类似的存储桶策略.

      I checked the bucket, and CloudFront had added a Bucket Policy similar to yours.

      分发被标记为 In Progress 一段时间.一旦它说 Enabled,我就通过 xxx.cloudfront.net URL 访问文件:

      The distribution was marked as In Progress for a while. Once it said Enabled, I accessed the files via the xxx.cloudfront.net URL:

      • xxx.cloudfront.net/public.jpg 重定向我到 S3 URL http://bucketname.s3.amazonaws.com/public.jpg代码>.是的,我可以看到该文件,但它不应使用重定向.
      • xxx.cloudfront.net/private.jpg 重定向我也,但后来我收到访问被拒绝,因为它是一个私人文件S3.
      • xxx.cloudfront.net/public.jpg redirected me to the S3 URL http://bucketname.s3.amazonaws.com/public.jpg. Yes, I could see the file, but it should not use a redirect.
      • xxx.cloudfront.net/private.jpg redirected me also, but I then received Access Denied because it is a private file in S3.

      然后我做了一些研究并发现这是相当普遍的现象.有些人通过将他们的 CloudFront 分配指向静态托管网站 URL 来使用一种解决方法,但这有一个缺点,即它不适用于 Origin Access Identity,我也怀疑它不会收到免费 S3 流量到边缘的折扣.

      I then did some research and found that this is quite a common occurrence. Some people use a workaround by pointing their CloudFront distribution to the static hosted website URL, but this has the disadvantage that it will not work with the Origin Access Identity and I also suspect it won't receive the 'free S3 traffic to the edge' discount.

      所以,我等了一夜,今天早上对其进行了测试,一切正常.

      So, I waited overnight, tested it this morning and everything is working fine.

      底线:即使它说ENABLED,事情也可能需要几个小时(例如一夜之间)才能恢复正常.然后它将按照文档工作.

      Bottom line: Even if it says ENABLED, things might take several hours (eg overnight) to get themselves right. It will then work as documented.