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

时间:2019-07-11 23:34:26

标签: javascript amazon-web-services amazon-s3 amazon-cognito

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

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

这是他们的代码,用于重定向尚未登录的用户。当用户尝试访问/rides.html

时,它将作为javascript运行
   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';
   });

在确定最佳方法以确保只有登录的用户才能访问我的网站的某些部分时,我遇到了很多麻烦。对于与webdev / AWS相关的任何事物来说都是非常新的东西,我在网上查找此信息时遇到了一些麻烦。

编辑:要清除我要实现的内容-我希望整个rides.html页面对于任何尚未登录的用户都无法访问。

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

1 个答案:

答案 0 :(得分:0)

我没有完成您提到的研讨会,但是通过阅读模块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"
        }
    ]
}

这将使除rides.html文件以外的所有对象公开。如果要访问它,则必须使用签名的URL。 [1]
请注意,不得将桶或对象ACL与该方法结合使用,该桶或对象ACL授予所有人公开访问权限,因为这可能会阻止对象保持私有状态。

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

由于文档[2]中的限制,我不知道以下各项是否可行,但是您可以尝试一下。
可以在 NotPrincipal 属性"Federated": "cognito-identity.amazonaws.com"中使用Web身份联合身份验证提供程序。 然后,您可以通过条件键(例如 cognito-identity.amazonaws.com:sub )来缩小哪个联盟用户可以访问rides.html对象。 [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