尝试通过我网站上的完整 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 禁止错误,并且使用屏幕截图中显示的设置对我有效
有一段时间,我只是将我网站的内容存储在一个 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 禁止错误,并且使用屏幕截图中显示的设置对我有效