已签名 URL 的 AWS CloudFront:403 访问被拒绝

AWS CloudFront with Signed URL: 403 Access Denied

我正在配置一个环境,其中 Amazon S3 Bucket 用于存储媒体文件,Amazon CloudFront 用于限制分发目的。

对这些媒体文件的访问需要保密,并且应该通过 签名的 URL 来完成。所以我在 South America (São Paulo) 区域创建了 S3 Bucket 并上传了一些测试文件。然后我创建了一个 CloudFront Distribution,之前的 bucket 作为 Origin 并且它的 Bucket Accessrestricted 。我创建了一个新的 OAI(原始访问身份)并选择了选项 Yes, Update Bucket Policy 以便它自动配置 S3 Bucket Policies。 我只使用 default Behavior 并且配置了 HTTP and HTTPS 查看器协议策略 GET, HEAD 允许的方法Restrict Viewer Access (Use Signed URLs or Signed Cookies) 已设置,Trusted Signer 已设置为 Self

这里有一些图片来阐明设置:

S3 存储桶策略

发行来源

分布的行为

我在尝试访问使用 awscli[=79= 生成的签名 URL 时收到 HTTP 403 ]

<Error>
    <Code>AccessDenied</Code>
    <Message>Access denied</Message>
</Error>

是不是少了什么我不知道的? docs 所说的一切我都做了。

在重新创建 Amazon S3 BucketAmazon CloudFront Distribution 之后,我仍然遇到这个问题。在与我的橡皮鸭交谈后,我发现我使用的 Private Key 文件属于已删除的 CloudFront Key-pair.

现在我正在使用正确的密钥来加密一切,一切正常。这并不能解释为什么第一个 bucketdistribution 不起作用,因为在那个特定情况下我使用的是 same 组配置和正确的 Private Key 文件。

我也遇到了同样的问题。可能,我们必须重新生成 Cloudfront 密钥对。

我收到了同样的 Access Denied 错误,并花了最后几个小时试图弄清楚发生了什么。我终于意识到 Expires 参数是过去设置的,因为我使用的是本地时间而不是 UTC。请确保将来根据 UTC 设置 Expires

在我的例子中,问题出在 URL 我传递给 URL 签名代码(我使用 AWS SDK for Node.js ).

cloudFront.getSignedUrl({
  url: `${distributionUrl}/${encodeURI(key)}`,
  expires: Math.floor(new Date().getTime() / 1000) + 60 * 60
})

备注encodeURI。我没有那样做。生成的签名 URL 仍会编码 URI 组件,但签名无效,从而导致 403 错误。

编辑:...您必须像这样将其包装到 url.format() 中:

cloudFront.getSignedUrl({
  url: url.format(`${distributionUrl}/${encodeURI(key)}`),
  expires: Math.floor(new Date().getTime() / 1000) + 60 * 60
})

我想他们应该在 SDK 中这样做。

我遇到了同样的问题,我为解决这个问题而执行的步骤是:

  • Distribution Settings 中,将 Default Root Object 设置为 index.html
  • Error pages 选项卡单击 Create Custom Error Response 并为 Http 错误代码 404 添加错误,响应页面路径设置为 /index.html