通过身份验证重定向在AWS S3上托管Angular SPA

通过身份验证重定向在AWS S3上托管Angular SPA,angular,amazon-web-services,amazon-s3,angular2-routing,Angular,Amazon Web Services,Amazon S3,Angular2 Routing,我们的SPA是用Angular2(即Angular2,Angular4.Not AngularJS)编写的,并使用OAuth2对Azure AD进行身份验证。我们使用an来处理身份验证 该应用程序托管在一个AWS S3 bucket中,该bucket配置为服务于静态网站。为了便于讨论,让我们假设URL是myapp.example.com 当用户单击“登录”按钮时,他们将被重定向到microsoft页面以处理身份验证。到目前为止,一切顺利。一旦他们通过身份验证,他们将被重定向回myapp.exam

我们的SPA是用Angular2(即Angular2,Angular4.Not AngularJS)编写的,并使用OAuth2对Azure AD进行身份验证。我们使用an来处理身份验证

该应用程序托管在一个AWS S3 bucket中,该bucket配置为服务于静态网站。为了便于讨论,让我们假设URL是
myapp.example.com

当用户单击“登录”按钮时,他们将被重定向到microsoft页面以处理身份验证。到目前为止,一切顺利。一旦他们通过身份验证,他们将被重定向回
myapp.example.com/login

但是,在我的S3存储桶中没有名为
login
的工件。
登录
路由由Angular router处理,并调用我的应用程序中的一个组件。当我在本地机器上运行时,这些都可以在开发中正常工作。但是当我运行S3中托管的版本时,重定向回
myapp.example.com/login
失败,出现404错误

我理解错误的原因-在我的S3存储桶中没有名为
login
的工件。但我想这对我应用程序中的任何链接都是一个问题。例如,如果我与另一个用户共享了一个指向
myapp.example.com/objects/1234
的链接,我想这对他们来说也是404


所以问题是,我需要做什么才能在AWS中正确地托管此SPA,以便重定向和其他链接正常工作?

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


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

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


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

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

这个问题实际上是在讨论中

注意:如果bucket和 请求者没有s3:ListBucket访问权限,那么请求者 接收HTTP 403访问被拒绝错误,而不是HTTP 404 错误。如果是这种情况,则必须解决与 缺少用于解决HTTP 403错误的对象

你只需要做两件事

  • 在CloudFront中添加一个
  • 更新您的bucket策略
  • 1)创建分发后,单击分发的ID返回设置。您应该看到多个选项卡,其中一个是错误页面。单击错误页面,然后单击创建自定义错误响应。从这里开始,您需要为404处理设置重定向,以确保SPA正常工作

    设置:

    • HTTP错误代码至404:未找到
    • 将最小TTL(秒)缓存为所需的默认值时出错。这是你的缓存
    • 是的自定义错误响应
    • 指向/index.html的响应页面路径
    • HTTP对200的响应代码:OK
    2)我们从知识中心了解到,如果对象不存在,并且您没有
    s3:ListBucket
    则会得到403而不是404。测试时,我们注意到您实际上得到了
    NoSuchKey
    。好的,知识中心给了我们解决方案,所以我们只需要更新bucket策略

    如果设置正确,CloudFront源站访问标识应该已经设置为bucket策略。它将看起来像:

    {
        "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漏洞


    参考资料:

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

    这个问题实际上是在讨论中

    注意:如果bucket和 请求者没有s3:ListBucket访问权限,那么请求者 接收HTTP 403访问被拒绝错误,而不是HTTP 404 错误。如果是这种情况,则必须解决与 缺少用于解决HTTP 403错误的对象

    你只需要做两件事

  • 在CloudFront中添加一个
  • 更新您的bucket策略
  • 1)创建分发后,单击分发的ID返回设置。您应该看到多个选项卡,其中一个是错误页面。单击错误页面,然后单击创建自定义错误响应。从这里开始,您需要为404处理设置重定向,以确保SPA正常工作

    设置:

    • HTTP错误代码至404:未找到
    • 将最小TTL(秒)缓存为所需的默认值时出错。这是你的缓存
    • 是的自定义错误响应
    • 指向/index.html的响应页面路径
    • HTTP对200的响应代码:OK
    2)我们从知识中心了解到,如果对象不存在,并且您没有
    s3:ListBucket
    则会得到403而不是404。测试时,我们注意到您实际上得到了
    NoSuchKey
    。好的,知识中心给了我们解决方案,所以我们只需要更新bucket策略

    如果你设置了这个属性