尝试通过我网站上的完整 url 访问页面时收到 AccessDenied

Receive AccessDenied when trying to access a page via the full url on my website

有一段时间,我只是将我网站的内容存储在一个 s3 存储桶中,并且可以通过完整 url 访问所有页面就好了。我想通过添加 SSL 使我的网站更安全,因此我创建了一个 CloudFront 分发以指向我的 s3 存储桶。

网站加载正常,但如果用户尝试刷新页面或者他们尝试使用完整 url(即 www.example.com/home), 他们将收到一个 AccessDenied 页面。

我的 s3 存储桶上有一个策略,该策略限制仅访问 Origin Access Identity,并且 index.html 被设置为我的域根对象。

我不明白我错过了什么。

要演示,请随时访问我的site

您会注意到它如何将您重定向到 kurtking。me/home。要重现错误,请尝试刷新页面或通过完整 URL(即 kurtking.me/life)

访问页面

非常感谢您的帮助,因为几天来我一直在努力解决这个问题并寻找答案。

我已经弄明白了,想 post 我的解决方案,以防其他人遇到这个问题。

问题是由于 Angular 是一个 SPA(单页应用程序),而我使用 S3 存储桶来存储它。当您尝试通过 url 访问权限转到特定页面时,CloudFront 将获取(例如 /about)并转到您的 S3 存储桶以查找该文件。因为 Angular 是一个 SPA,该文件在技术上不存在于您的 S3 存储桶中。这就是我收到错误的原因。

我需要做些什么来修复它

如果您在 Cloudfront 中打开您的分配,您将看到一个 'Error Pages' 选项卡。我不得不添加两个处理 400 和 403 的 'Custom Error Responses'。400 和 403 的细节相同,所以我只包含 400 的照片。见下文:

基本上,发生的事情是告诉 Cloudfront,无论出现 400 还是 403 错误,重定向回 index.html,从而将控制权交给 Angular 以决定它是否可以转到路径与否。如果您想为客户端提供 400 或 403 错误,您需要在 Angular 中定义这些路由。

设置两个自定义错误响应后,我部署了我的云端解决方案和 wallah,它成功了!

我使用了以下 article 来帮助指导我找到这个解决方案。

解决此问题的更好方法是允许列表存储桶权限并为云端添加 404 错误自定义规则以指向 index.html。 WAF 也会返回 403 错误,如果将它们添加到 index.html 用于自定义错误处理,将会导致额外的安全问题。因此,对于 angular 个应用程序,最好首先避免从 S3 收到 403 错误。

接受的答案似乎有效,但似乎不是一个好的做法。相反,检查云端源是否设置为 S3 Bucket(静态文件位于其中) 实际的 s3 url 端点。它应该是 s3 url 端点而不是 s3 存储桶。

终点后的url应该是原点

如果您在使用 CDK 时遇到此问题,您需要添加以下内容:

MyAmplifyApp.addCustomRule({
  source: '</^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>',
  target: '/index.html',
  status: amplify.RedirectStatus.REWRITE
});

对于那些试图使用 terraform 实现此目的的人,您只需将其添加到您的 CloudFront 配置中:

resource "aws_cloudfront_distribution" "cf" {
   ...

   custom_error_response {
   error_code    = 403
   response_code = 200
   response_page_path = "/index.html"
   }
   
   ...
   
}

添加 Cloudfront 函数以将请求的 uri 重写为 /index.html(如果它与正则表达式不匹配)。

例如,如果 none 的 SPA 路线包含“.” (点),你可以这样做:

function handler(event) {
    var request = event.request
    if (/^(?!.*\..*).*$/.test(request.uri)) {
        request.uri = '/index.html'
    }
    return request
}

这可以解决重定向 403 -> index.html 时可能产生的任何副作用。例如,如果您使用 WAF 通过 IP 地址限制访问,如果您尝试从“错误的 IP”导航到该网站,则会抛出 403,但使用之前建议的 403 -> index.html 重定向,您仍然会看到 index.html。使用云端功能,您不会。

请从控制台检查您遇到的错误。在我的例子中,我遇到了 403 禁止错误,并且使用屏幕截图中显示的设置对我有效