【问题标题】:AWS architecture to handle rights management for file access in AWS S3用于处理 AWS S3 中文件访问权限管理的 AWS 架构
【发布时间】:2020-01-01 22:13:18
【问题描述】:

简而言之:授予和控制最终用户访问存储在 S3 存储桶中的文件的最佳方式是什么,并为最终用户所属的“组”中的每个文件确定特定的访问规则当有很多动态定义的“组”(超过 100 000 个)并且每个用户可以是多个“组”(超过 1000 个)的一部分时,他在那个“组”中的角色是什么。

我所在的团队正在开发基于 AWS lambda 的产品,可通过 Web 应用程序访问。该产品采用微服务架构开发。 为了解释我们的用例,假设我们有 3 个微服务:

  • 用户服务,其实就是AWS Cognito(全平台处理用户和授权)
  • 公司服务。由我们开发,基于 AWS Lambda 和 dynamoDB。管理公司信息(名称、人员和其他元数据,我不会在这里解释)
  • 文档服务。我们需要开发的这项服务需要处理属于公司的文件。

在架构方面,我们在处理以下用例时有一些困难:

我们希望属于一家或多家公司的人员能够访问该文档(文件)。这些人可能在公司内部担任某些角色(执行、人力资源、销售)。根据这些角色,人们可能只能访问公司文档的一部分。 当然,不属于公司的人将无法访问该公司的文件。

为了处理此类用例,我们希望使用 AWS S3,并且如果可能的话,不要重新开发我们自己的可以代理 AWS S3 的微服务。

问题是:我们如何使用 AWS S3 为我们的用例管理权限?

我们研究了多种解决方案。

  1. 使用限制 S3 文件访问的 IAM 策略(WEB 应用程序直接访问 S3,无代理)。 如果我们的 S3 存储桶是按公司名称/UUID(S3 根目录下的文件夹)组织的,我们可以考虑在每次创建公司时创建一个 IAM 策略并对其进行配置,以便公司中的每个用户都可以访问该公司文件夹,并且只有那个文件夹。

  2. 无法为每个公司创建存储桶,因为 AWS 将 S3 存储桶的数量限制为每个 AWS 账户 100(或 1000)个。而我们的产品可能有1000多家公司

  3. 无法将用户放入组(组 == 1 家公司),因为每个用户池的组数为 500。

  4. 使用代理 AWS S3 调用的 lamda@edge 来验证 S3 中的文件 URI 是否已授权给请求的用户(用户属于公司并具有读取其文档的正确角色)。此 Lambda@edge 将调用内部服务以了解此用户是否有权从该公司获取文件(基于调用的 URL)

  5. 使用 AWS S3 预签名 URL。我们可以创建自己的文档服务,公开 CREATE、GET、DELETE api,在完成授权检查(用户属于公司)后联系 AWS S3 服务并生成预签名 URL 以上传或获取文件。然后用户(WebApp)会直接调用S3。

事实上,如果我试图总结我们的问题,我们在使用 AWS lambda 开发的 AWS 产品中处理混合 RBAC 和授权控制以及将 AWS S3 暴露给最终用户时会遇到一些困难。

如果您对此类用例有经验或建议,我们将非常欢迎您提出建议。

【问题讨论】:

    标签: amazon-web-services amazon-s3 rbac aws-serverless serverless-architecture


    【解决方案1】:

    我会考虑使用 STS 为特定角色和策略(可以动态定义)生成临时凭据。所以基本上它或多或少是你的第一,除了你不必预先创建所有这些策略,你可以动态地构建它们。

    类似的东西:

    AWSSecurityTokenService client = AWSSecurityTokenServiceClientBuilder.standard().build();
    AssumeRoleRequest request = new AssumeRoleRequest()
        .withRoleArn("arn:aws:iam::123456789012:role/sales")
        .withRoleSessionName("Scott Tiger")
        .withPolicy("{\"Version\":\"2012-10-17\"," +
           "\"Statement\":[{\"Sid\":\"Stmt1\",\"Effect\":\"Allow\",\"Action\":\"s3:GetObject\"," +
           "\"Resource\":\"arn:aws:s3:::document_storage_bucket/" + company + "/" + department + "/*\"}]}");
    AssumeRoleResult response = client.assumeRole(request);
    

    (抱歉换行了。)

    这将为您提供具有角色基于身份的策略和会话策略交集的权限的凭据。

    然后,您可以将这些凭据传递给用户,生成预签名 URL,无论您需要什么。

    【讨论】:

    • 感谢@lexicore 的回答。我们将研究这个解决方案。在您的示例中,您提到了一个角色,但我认为这很难用于 S3 权限,因为附加的策略也必须是动态的。例如,角色 sales 只能访问/company_name/sales/*。但我认为 STS 中定义的动态策略对我们来说已经足够了。
    • @Joris.B 角色在那里并不太重要,您可以只使用一个标准角色来处理所有事情,或者如果有与这些角色等效的功能,则可以只使用几个角色。
    【解决方案2】:

    对我来说,我会选择第 5 个解决方案:

    1 - 这将允许您完全按照您的设计方式管理您的权利,而没有太多限制。您还可以轻松地吸收您的授权规则的任何更改。

    2 - 文档下载功能因此与 S3 不完全耦合。如果您想稍后再进行其他实现(EDM、动态生成等),您可以从您的网关进行管理,甚至可以同时使用多个系统。

    【讨论】:

      【解决方案3】:

      我正在回答我的问题,向您展示我们的最终决定。

      我们选择了基于预签名 URL 的解决方案,这将让我们:

      • 独立于 AWS S3(可以从 S3 更改为另一种文件存储服务而无需太多成本)
      • 不向我们的客户端(网络应用程序)公开 S3 API,而只是网络应用程序可以进行本地上传或下载文件的 URL
      • 权限管理在服务本身(doc-service)内部完成,授权完成后会生成预签名的URL
      • 进行权限管理的信息来自 Cognito(身份验证)和公司服务(授权)

      Bellow,一个基于 AWS lambda 的架构图:

      【讨论】:

        猜你喜欢
        • 2022-01-05
        • 2022-12-09
        • 2017-05-17
        • 1970-01-01
        • 2014-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多