使用身份验证重定向在AWS S3上托管Angular SPA

时间:2017-06-02 18:36:27

标签: angular amazon-web-services amazon-s3 angular2-routing

我们的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,以便重定向和其他链接正常工作?

2 个答案:

答案 0 :(得分:1)

这是一个古老的话题,但是我在从事类似项目时发现了这一点。使用Lambda并非理想之选,因此我将其作为更新的答案,以帮助其他人搜索此问题。

此问题实际上在Knowledge Center中。

  

注意:如果存储桶中不存在请求的对象,则   请求者没有s3:ListBucket访问权限,那么请求者   收到HTTP 403访问被拒绝错误而不是HTTP 404   错误。在这种情况下,您必须解决与   缺少对象来解决HTTP 403错误。

您只需要做两件事。

  1. 向CloudFront添加custom error page
  2. 更新您的存储桶策略

1)创建分配后,单击分配ID即可返回到设置。您应该看到多个标签,其中一个是错误页面。点击错误页面,然后点击创建自定义错误响应。从这里开始,您需要为404处理设置重定向,以确保您的SPA正常工作

设置:

  • HTTP错误代码 404:找不到
  • 错误缓存最小TTL(秒)缓存到所需的任何值,默认情况下有效。这是您的缓存。
  • 自定义错误响应
  • 响应页面路径 /index.html
  • HTTP响应代码 200:确定

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>

参考:Guide I wrote while working on a similar project

答案 1 :(得分:0)

在S3前面配置AWS CloudFront,并为CloudFront(使用CNAME)执行域映射。然后使用AWS Edge Lambda,您可以重写/ login的URL以指向index.html。

这将为/ login路径加载index.html,并在重定向发生后从客户端触发Angular中的路由。