AWS Cognito - 将部分静态 S3 网站限制为登录用户

kjm*_*jmj 5 javascript amazon-s3 amazon-web-services amazon-cognito

我正在构建一个托管在 s3 上的小型静态网站。我使用 Cognito 来启动和运行一些基本的用户验证(登录、注销)。我想将网站的某些部分限制为仅登录用户。

我完成了本研讨会https://github.com/aws-samples/aws-serverless-workshops/tree/master/WebApplication 的模块 2 。在本次研讨会中,页面/rides.html仅限于登录用户。如果您未登录并尝试访问/rides.html,页面将开始加载,然后快速将您重定向到/signin.html。这样做的问题是未经授权的用户仍然可以在重定向发生前的一瞬间看到游乐设施页面。

这是他们处理重定向未登录用户的代码。当用户尝试访问时,它作为 javascript 运行 /rides.html

   WildRydes.authToken.then(function setAuthToken(token) {
       if (token) {
           authToken = token;
       } else {
           window.location.href = '/signin.html';
       }
   }).catch(function handleTokenError(error) {
       alert(error);
       window.location.href = '/signin.html';
   });
Run Code Online (Sandbox Code Playgroud)

我在确定确保只有登录用户才能访问我网站部分内容的最佳方式时遇到了很多麻烦。对任何与 webdev/AWS 相关的东西都很陌生,我在网上查找这些信息时遇到了一些麻烦。

编辑:为了明确我想要实现的目标 - 我希望所有rides.html未登录的人都无法访问整个页面。

解决方案:我们最终在 s3 存储桶前面放置了一个受限的 CloudFront。然后,当有人尝试访问 CloudFront 时,我们触发了 lambda。这是一个教程:https : //douglasduhaime.com/posts/s3-lambda-auth.html

Mar*_*per 1

我没有完成您提到的研讨会,但通过阅读模块 2 的自述文件,我了解到他们正在使用 Amazon Cognito 用户池实现用户身份验证和注册

从无法访问的站点重定向是可以的,您不能确保它永远不会加载。让我解释一下原因:

网站上显示的“敏感”信息不是静态的。它是从模块 4 中的 REST 后端加载的。由于身份验证是通过 JWT静态进行的,因此如果用户未经身份验证,则永远不会从 REST 后端加载数据。

那么页面应该做什么呢/rides.html

  • 如果用户经过身份验证(即已获得有效的 JWT),则应调用 REST 后端来获取数据
  • 如果用户未经过身份验证(即不存在 JWT)或存在 JWT 并且不再有效,则应将用户重定向到登录页面;请注意,在重定向之前没有从 REST 后端获取任何有意义的数据

编辑:

为了限制对 S3 中单个对象的访问,您可以向 s3 存储桶添加如下所示的存储桶策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::<your-bucket-name>/*"
        },
        {
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": "<your-user-arn>"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::<your-bucket-name>/rides.html"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

这将使除rides.html文件之外的所有对象公开。如果您想访问它,则必须使用签名的网址。[1]
请注意,您不得将向每个人授予公共访问权限的存储桶或对象 ACL 与此方法结合使用,因为这可能会阻止对象保持私有状态。

另一种方法(使用联合用户而不是常规 IAM 用户)

由于文档 [2] 的限制,我不知道以下内容是否有效,但您可以尝试一下。
可以在NotPrincipal属性中使用 Web 联合身份验证提供程序:"Federated": "cognito-identity.amazonaws.com"rides.html然后,您可以通过条件键(例如cognito-identity.amazonaws.com:sub )缩小哪些联合用户有权访问该对象。[3]

[1] https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html

[2] https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html

[3] https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html