我们的SPA是用Angular编写的(即Angular2,Angular4。不是AngularJS),并使用OAuth2对Azure AD进行身份验证。我们使用OIDC library来处理身份验证。
该应用程序托管在配置为静态网站服务的AWS S3存储桶中。为了论证,我们假装URL为myapp.example.com
。
当用户单击登录按钮时,会将其重定向到Microsoft页面以处理身份验证。到现在为止还挺好。经过身份验证后,系统会将其重定向回myapp.example.com/login
。
但是我的S3存储桶中没有名为login
的工件。 login
路由由Angular路由器处理,并在我的应用程序中调用组件。当我在本地机器上运行时,这一切都可以正常开发。但是,当我运行S3中托管的版本时,重定向回myapp.example.com/login
会因404错误而失败。
我理解错误的原因 - 我的S3存储桶中没有名为login
的工件。但我想这对于我的应用程序中的任何链接都是一个问题。例如,如果我与其他用户共享了myapp.example.com/objects/1234
的链接,我想这也是404。
所以问题是,我需要做些什么才能在AWS中正确托管此SPA,以便重定向和其他链接正常工作?
答案 0 :(得分:1)
这是一个古老的话题,但是我在从事类似项目时发现了这一点。使用Lambda并非理想之选,因此我将其作为更新的答案,以帮助其他人搜索此问题。
此问题实际上在Knowledge Center中。
注意:如果存储桶中不存在请求的对象,则 请求者没有s3:ListBucket访问权限,那么请求者 收到HTTP 403访问被拒绝错误而不是HTTP 404 错误。在这种情况下,您必须解决与 缺少对象来解决HTTP 403错误。
您只需要做两件事。
1)创建分配后,单击分配ID即可返回到设置。您应该看到多个标签,其中一个是错误页面。点击错误页面,然后点击创建自定义错误响应。从这里开始,您需要为404处理设置重定向,以确保您的SPA正常工作
设置:
2)我们从知识中心获悉,如果对象不存在,并且您没有s3:ListBucket
,则会得到403而不是404。在测试时,我们注意到您实际上得到了NoSuchKey
。好的,知识中心为我们提供了解决方案,因此我们只需要更新存储桶策略即可。
如果正确设置,则应该已经将CloudFront Origin Access Identity设置为存储桶策略。看起来像这样:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ORIGIN_ACCESS_ID"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BUCKET_NAME/*"
}
]
}
现在,您只需要添加新参数。同样重要的是要注意,此新参数使用其他资源。因此,新政策现在应类似于:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontOriginAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ORIGIN_ACCESS_ID"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::BUCKET_NAME",
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
您的SPA现在应该可以正常工作了,而不会受到任何Lambda的攻击。</ p>
答案 1 :(得分:0)
在S3前面配置AWS CloudFront,并为CloudFront(使用CNAME)执行域映射。然后使用AWS Edge Lambda,您可以重写/ login的URL以指向index.html。
这将为/ login路径加载index.html,并在重定向发生后从客户端触发Angular中的路由。