SaaS 租户隔离与基于属性的访问控制 (ABAC),使用 AWS STS 在 JWT 中支持标签
使用 AWS STS 支援 JWT 标签的 ABAC 进行 SaaS 租户隔离
由 Manuel Heinkel 和 Alex Pulver 于 2024 年 6 月 17 日发表在 进阶 (300),安全性、身份与合规性,技术操作永久链接评论 分享
免费加速器官方正版下载主要观点
随著独立软体供应商 (ISVs) 向多租户 SaaS 模型转型,租户隔离成为一个重要的安全考量。AWS 提供的 IAM 可以有效实现租户隔离,特别是透过 ABAC 和 AWS STS 的应用。本文介绍了一种使用 AWS STS 的 AssumeRoleWithWebIdentity API 操作,并通过 JWT 的标签实现租户隔离的方法。随著独立软体供应商 (ISVs) 逐渐向多租户软体即服务 (SaaS) 模型转型,这些供应商通常采用共享基础架构模型以实现成本和运营效率。然而,ISVs 迁移至多租户模型后,对于一个租户能否访问另一个租户资源的潜在风险的担忧会愈发增加。为此,SaaS 系统必须包括能够确保每个租户的资源即使在共享基础架构上运行也能被隔离的明确机制。
我们称之为 租户隔离。租户隔离的核心理念是您的 SaaS 架构应引入严格控制资源访问的结构,并阻止试图访问其他租户资源的行为。
AWS 身份与访问管理 (IAM) 是您可以用来安全管理身份和访问 AWS 服务与资源的服务。您可以利用 IAM 实现租户隔离。使用 IAM,主要有三种隔离方法,如如何使用 ABAC 和 AWS IAM 实现 SaaS 租户隔离博客所述,这三种方法分别是动态生成的 IAM 策略、基于角色的访问控制 (RBAC) 及基于属性的访问控制 (ABAC)。前面提到的部落格文章提供了使用 AWS 安全令牌服务 (AWS STS) 的 AssumeRole API 操作和会话标签来实现 ABAC 的租户隔离的示例。如果您对这些概念不熟悉,我们建议您先阅读该部落格文章以了解该模式的安全考虑。
在本文中,您将了解如何通过使用 AWS STS 的 AssumeRoleWithWebIdentity API 操作以及 JSON Web Token (JWT) 中的 https//awsamazoncom/tags 声明来实现租户隔离的替代方法。AssumeRoleWithWebIdentity API 操作验证 JWT,并根据 JWT 中的标签生成针对租户的临时安全凭证。
架构概述
下面我们来看看一个使用共享基础架构模型的多租户 SaaS 应用示例。
图 1:示例多租户 SaaS 应用程式架构
使用者导航至前端应用程式。前端应用程式将使用者重定向至身份提供者以进行身份验证。身份提供者返回一个 JWT 给前端应用程式。前端应用程式在伺服器端储存令牌。身份提供者将 https//awsamazoncom/tags 声明添加至 JWT,如下文配置部分详细说明。标签声明包含使用者的租户 ID。前端应用程式用 JWT 进行伺服器端 API 呼叫至后端应用程式。后端应用程式调用 AssumeRoleWithWebIdentity,传递其 IAM 角色的 Amazon Resource Name (ARN) 和 JWT。AssumeRoleWithWebIdentity 验证 JWT,将 JWT https//awsamazoncom/tags 声明中的租户 ID 标签映射至会话标签,并返回针对租户的临时安全凭证。后端 API 使用针对租户的临时安全凭证获取租户资料。假定的 IAM 角色的策略在使用 awsPrincipalTag 变数来限制访问。配置
接下来,我们来看看配置此机制所需的步骤。
步骤 1 配置带有标签声明的 OIDC 提供者
AssumeRoleWithWebIdentity API 操作需要JWT 中包含 https//awsamazoncom/tags 声明。需要将您的身份提供者配置为在其创建的 JWT 中包含此声明。以下是一个示例令牌,其中包括 TenantID 作为主体标签每个标签可以有一个单一值。确保用您自己的数据替换 ltTENANTIDgt。
json{ sub johndoe aud acoicclient jti ZYUCeRMQVtqHypVPWAN3VB iss https//examplecom iat 1566583294 exp 1566583354 authtime 1566583292 https//awsamazoncom/tags { principaltags { TenantID [ltTENANTIDgt] } }}
Amazon Cognito 最近推出了令牌自定义流程的改进,允许您在运行时添加数组、映射和 JSON 对象到身份和访问令牌,方法是使用预令牌生成 AWS Lambda 触发器。您需要启用高级安全功能,并配置您的用户池以接受版本 2 的 Lambda 事件的响应。
以下是 Lambda 触发器代码片段,显示如何将标签声明添加到 JWT此示例中的 ID 令牌:
pythondef lambdahandler(event context) event[response][claimsAndScopeOverrideDetails] = { idTokenGeneration { claimsToAddOrOverride { https//awsamazoncom/tags { principaltags { TenantID [ltTENANTIDgt] } } } } } return event
步骤 2 设置 IAM OIDC 身份提供者
接下来,您需要在 IAM 中创建一个OpenID Connect (OIDC) 身份提供者。IAM OIDC 身份提供者是在 IAM 中的实体,描述支持OIDC标准的外部身份提供者服务。当您想在 OIDC 兼容的身份提供者与您的 AWS 帐户之间建立信任时,使用 IAM OIDC 身份提供者。
在创建 IAM OIDC 身份提供者之前,您必须在身份提供者中注册您的应用,以接收客户端 ID。客户端 ID也称为 audience是注册时颁发给您的唯一标识符。
步骤 3 创建 IAM 角色
接下来的步骤是创建一个 IAM 角色,建立 IAM 和您组织的身份提供者之间的信任关系。此角色必须指定您的身份提供者作为联合的主体受信实体。此角色还定义了经过您组织的身份提供者验证的用户在 AWS 中能够执行的操作。在创建显示谁可以假定角色的信任策略时,您必须指定您在 IAM 中早前创建的 OIDC 提供者。
您可以使用AWS OIDC 条件上下文键编写策略,以限制联合用户访问与特定提供者、应用或用户相关的资源。这些键通常用于角色的信任策略。使用 OIDC 提供者的名称ltYOURPROVIDERIDgt后接声明来定义条件键,例如步骤 2 中的客户端 IDaud。
以下是一个 IAM 角色信任策略的示例。确保用您的数据替换 ltYOURPROVIDERIDgt 和 ltAUDIENCEgt。
json{ Version 20121017 Statement [ { Effect Allow Principal { Federated arnawsiam123456789012oidcprovider/ltYOURPROVIDERIDgt/ } Action [ stsAssumeRoleWithWebIdentity stsTagSession ] Condition { StringEquals { ltYOURPROVIDERIDgtaud ltAUDIENCEgt } } } ]}
例如,应用程式可以使用每个租户前缀将租户资产存储在 Amazon Simple Storage Service (Amazon S3) 中。您可以在 IAM 策略的 Resource 元素中使用 awsPrincipalTag 变数来实现租户隔离。IAM 策略可以引用 JWT https//awsamazoncom/tags 声明中定义的主体标签。
以下是一个 IAM 策略示例。确保用自己的数据替换 ltS3BUCKETgt。

json{ Version 20121017 Statement [ { Action s3GetObject Resource arnawss3ltS3BUCKETgt/{awsPrincipalTag/TenantID}/ Effect Allow } ]}
AssumeRoleWithWebIdentity 与 AssumeRole 的不同之处
使用 AssumeRole API 操作时,应用程式需要执行以下步骤:1验证 JWT;2从 JWT 中提取租户 ID 并将其映射到会话标签;3调用 AssumeRole 以假定应用程序提供的 IAM 角色。这种方法提供了应用程序独立定义租户 ID 会话标签格式的灵活性。
我们看到客户将此功能包装在共享库中,以减少应用程序团队的重复工作。每个应用都需要安装此库,这运行著控制租户隔离的敏感自定义代码。SaaS 提供者需要为他们使用的每种程式语言开发一个库,并为每个应用运行库升级活动。
而使用 AssumeRoleWithWebIdentity API 操作时,应用程式只需调用 API 及传递 IAM 角色和 JWT。AssumeRoleWithWebIdentity 验证 JWT 并生成根据 JWT https//awsamazoncom/tags 声明中的租户 ID 标签生成的针对租户的临时安全凭证。AWS STS 将租户 ID 标签映射到会话标签。客户可以使用各种编程语言可用的 AWS SDK 来调用 API。详情请参见 AssumeRoleWithWebIdentity API 操作文档。
此外,身份提供者现在对应用程序强制执行租户 ID 会话标签格式。因为 AssumeRoleWithWebIdentity 使用了 JWT 中的租户 ID 标签键和值。
结论
在这篇文章中,我们展示了如何使用 AssumeRoleWithWebIdentity API 操作在多租户 SaaS 应用程序中实现租户隔离。文中描述了应用架构、数据访问流以及如何配置应用程式使用 AssumeRoleWithWebIdentity。将 JWT 验证和将租户 ID 映射到会话标签的工作外包,可以简化应用架构并提高安全性。
要尝试这种方法,请按照 使用 AWS STS 支持 JWT 标签的 ABAC 实现 SaaS 租户隔离 步骤进行操作。了解更多有关使用会话标签的信息,请参见 IAM 文档中的在 AWS STS 中传递会话标签。
如对此篇文章有任何反馈,请在下方的评论区提交您的意见。如果您对本文有任何问题,请联系 AWS 支持。
Manuel Heinkel
Manuel 是 AWS 的解决方案架构师,与德国的软体公司合作,帮助他们在云端构建创新、安全的应用程式。他支持客户解决商业挑战并在 AWS 上取得成功。Manuel 在安全性和 SaaS 主题方面具有良好记录。在工作之余,他喜欢花时间与家人相处和探索山地。
Alex Pulver
Alex 是 AWS 的首席解决方案架构师。他帮助客户设计满足业务需求的流程和解决方案。目前,他的兴趣领域包括产品工程、开发者体验和平台战略。他是应用设计框架 (ADF)的创建者,旨在使业务与技术对齐,减少重工,并实现渐进式架构。
标签:AWS STS、JWT、SaaS、安全博客、标签
使用 Amazon Comprehend 创建的自定义元数据通过 Amazon Kendra 智能处
利用 Amazon Comprehend 创建的自定义元数据智能处理保险索赔关键要点保险公司面临日益增长的索赔处理需求与复杂性。Amazon Comprehend 和 Amazon Kendra 可以通过自定义元数据结合使用,提升保险索赔的处理效率。此解决方案通过自定义分类和实体识别,帮助组织更好地...