处理 AWS S3 文件访问权限管理的 AWS 架构
AWS architecture to handle rights management for file access in AWS S3
简而言之:授予和控制最终用户对存储在 S3 存储桶中的文件的访问权限的最佳方式是什么? ” 当有很多动态定义的“组”(超过 100 000 个)并且每个用户可以属于多个“组”(超过 1000 个)时,最终用户属于他在那个“组”中的角色是什么.
我所在的团队正在开发基于 AWS lambda 的产品,可通过 Web 应用程序访问。该产品采用微服务架构开发。
为了解释我们的用例,假设我们有 3 个微服务:
- 用户服务,即AWS Cognito(在整个平台处理用户和授权)
- 公司服务。由我们开发,基于 AWS Lambda 和 dynamoDB。管理公司信息(名称、人员和其他我不会在这里解释的元数据)
- 文档服务。我们要开发的这个服务,需要处理属于某公司的文件。
在架构方面,我们在处理以下用例方面有些困难:
我们希望属于一家或多家公司的人员可以访问该文档(文件)。这些人可能在公司内部担任某些职务(行政、人力资源、销售)。根据这些角色,人们可能只能访问公司文档的一部分。
当然,不属于公司的人将无法访问该公司的文件。
为了处理此类用例,我们希望使用 AWS S3,如果可能的话,无需重新开发我们自己的可能代理 AWS S3 的微服务。
问题是:我们如何使用 AWS S3 为我们的用例管理权限?
我们研究了多种解决方案。
使用限制 S3 文件访问的 IAM 策略(WEB 应用程序直接访问 S3,无代理)。
如果我们的S3 bucket是按公司name/UUID组织的(文件夹在S3的根目录),我们可以考虑在每次创建公司时创建一个IAM策略并配置它,以便公司中的每个用户都可以访问公司文件夹,而且只有那个文件夹。
不可能为每个公司创建一个存储桶,因为 AWS 将 S3 存储桶的数量限制为每个 AWS 帐户 100(或 1000)。而我们的产品可能有1000多家公司
无法将用户放入组(组 == 1 个公司),因为每个用户池的组数为 500。
使用代理 AWS S3 调用的 lamda@edge 来验证 S3 中的文件 URI 是否已为请求的用户授权(用户属于公司并具有阅读其文档的正确角色)。此 Lambda@edge 将调用内部服务以了解此用户是否有权从该公司获取文件(基于调用 URL)
使用 AWS S3 预签名 URL。我们可以创建自己的文档服务,公开 CREATE、GET、DELETE api,在完成授权检查(用户属于公司)后将联系 AWS S3 服务并生成预签名 URL 到上传或获取文件。然后用户(WebApp)会直接调用S3。
事实上,如果我试图总结我们的问题,我们在使用 AWS lambda 开发的 AWS 产品中处理 RBAC 和授权控制的混合,以及向最终用户公开 AWS S3 有一些困难。
如果您对此类用例有经验或建议,将非常欢迎您的建议。
我会考虑使用 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,无论您需要什么。
至于我,我会选择第 5 种解决方案:
1 - 这将允许您完全按照您设计的方式管理您的权利,而没有太多限制。您还将轻松吸收授权规则的任何更改。
2 - 因此,文档下载功能并未与 S3 完全耦合。如果您稍后想使用其他实现(EDM、动态生成等),您可以从您的网关进行管理,甚至可以同时使用多个系统。
我回答我的问题是为了向您展示我们的最终决定。
我们选择了基于预签名 URL 的解决方案,这将使我们:
- 独立于 AWS S3(可以从 S3 更改为另一种文件存储服务而无需太多成本)
- 不向我们的客户端(Web 应用程序)公开 S3 API,而只是 URL Web 应用程序可以进行本机上传或下载文件的地方
- 权限管理在服务本身(doc-service)内部完成,授权完成后会生成预签名URL
- 做权限管理的信息来自Cognito(认证)和公司服务(授权)
下面是一个基于 AWS lambda 的架构图:
简而言之:授予和控制最终用户对存储在 S3 存储桶中的文件的访问权限的最佳方式是什么? ” 当有很多动态定义的“组”(超过 100 000 个)并且每个用户可以属于多个“组”(超过 1000 个)时,最终用户属于他在那个“组”中的角色是什么.
我所在的团队正在开发基于 AWS lambda 的产品,可通过 Web 应用程序访问。该产品采用微服务架构开发。 为了解释我们的用例,假设我们有 3 个微服务:
- 用户服务,即AWS Cognito(在整个平台处理用户和授权)
- 公司服务。由我们开发,基于 AWS Lambda 和 dynamoDB。管理公司信息(名称、人员和其他我不会在这里解释的元数据)
- 文档服务。我们要开发的这个服务,需要处理属于某公司的文件。
在架构方面,我们在处理以下用例方面有些困难:
我们希望属于一家或多家公司的人员可以访问该文档(文件)。这些人可能在公司内部担任某些职务(行政、人力资源、销售)。根据这些角色,人们可能只能访问公司文档的一部分。 当然,不属于公司的人将无法访问该公司的文件。
为了处理此类用例,我们希望使用 AWS S3,如果可能的话,无需重新开发我们自己的可能代理 AWS S3 的微服务。
问题是:我们如何使用 AWS S3 为我们的用例管理权限?
我们研究了多种解决方案。
使用限制 S3 文件访问的 IAM 策略(WEB 应用程序直接访问 S3,无代理)。 如果我们的S3 bucket是按公司name/UUID组织的(文件夹在S3的根目录),我们可以考虑在每次创建公司时创建一个IAM策略并配置它,以便公司中的每个用户都可以访问公司文件夹,而且只有那个文件夹。
不可能为每个公司创建一个存储桶,因为 AWS 将 S3 存储桶的数量限制为每个 AWS 帐户 100(或 1000)。而我们的产品可能有1000多家公司
无法将用户放入组(组 == 1 个公司),因为每个用户池的组数为 500。
使用代理 AWS S3 调用的 lamda@edge 来验证 S3 中的文件 URI 是否已为请求的用户授权(用户属于公司并具有阅读其文档的正确角色)。此 Lambda@edge 将调用内部服务以了解此用户是否有权从该公司获取文件(基于调用 URL)
使用 AWS S3 预签名 URL。我们可以创建自己的文档服务,公开 CREATE、GET、DELETE api,在完成授权检查(用户属于公司)后将联系 AWS S3 服务并生成预签名 URL 到上传或获取文件。然后用户(WebApp)会直接调用S3。
事实上,如果我试图总结我们的问题,我们在使用 AWS lambda 开发的 AWS 产品中处理 RBAC 和授权控制的混合,以及向最终用户公开 AWS S3 有一些困难。
如果您对此类用例有经验或建议,将非常欢迎您的建议。
我会考虑使用 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,无论您需要什么。
至于我,我会选择第 5 种解决方案:
1 - 这将允许您完全按照您设计的方式管理您的权利,而没有太多限制。您还将轻松吸收授权规则的任何更改。
2 - 因此,文档下载功能并未与 S3 完全耦合。如果您稍后想使用其他实现(EDM、动态生成等),您可以从您的网关进行管理,甚至可以同时使用多个系统。
我回答我的问题是为了向您展示我们的最终决定。
我们选择了基于预签名 URL 的解决方案,这将使我们:
- 独立于 AWS S3(可以从 S3 更改为另一种文件存储服务而无需太多成本)
- 不向我们的客户端(Web 应用程序)公开 S3 API,而只是 URL Web 应用程序可以进行本机上传或下载文件的地方
- 权限管理在服务本身(doc-service)内部完成,授权完成后会生成预签名URL
- 做权限管理的信息来自Cognito(认证)和公司服务(授权)
下面是一个基于 AWS lambda 的架构图: