所有文章 > API安全 > 如何实现基于属性的API访问控制
如何实现基于属性的API访问控制

如何实现基于属性的API访问控制

在讨论访问控制时,可能会遇到两种常见的方法。第一种基于角色的访问控制 (RBAC) 方法,可以说是更广为人知的,更加传统的。然而,还有第二种选择,即基于属性的访问控制 (ABAC),它提供了更高的粒度和可扩展性。但 ABAC 究竟是如何工作的,RBAC 和 ABAC 之间有什么区别?

下面,我们将深入研究 RBAC 和 ABAC,并开始对它们有一个清晰的认识。然后,我们将从高层次了解如何实施 ABAC 来增强 API 安全性。

什么是基于角色的访问控制 (RBAC)?

在讨论基于属性的访问控制时,首先了解基于角色的访问控制工作原理会有所帮助。对于具有多种类型用户的系统,您可以根据这些用户在组织内以及系统本身内所扮演的特定角色来划分这些用户。例如,执行管理操作的用户(如系统管理员)的需求级别高于销售代表。因此,该用户可能需要比其他员工更高的底层系统访问权限级别,具体由角色决定。

在功能方面,这意味着对每个访问它的角色的功能和资源进行限制。前面提到的系统管理员可能有权访问内部访问控制功能,或者可以访问特权信息。相反,该销售代表可能只能访问试用身份验证码生成或基本用户功能等元素。

虽然 RBAC 在控制访问方面做得还不错,但它也存在一些明显的缺点。

RBAC 的缺点

首先,RBC 模型有一个关键的弱点——将角色映射到操作并不总是很清晰。在我们的销售代表示例中,如果组织决定销售代表应该能够创建用户帐户以进行演示,该怎么办?访问控制基础知识告诉我们,我们不想让他们成为管理员,但他们当前的角色不符合他们的需要。在这种情况下,我们唯一的解决方案是创建一个新角色。可以立即创建销售代表提升角色。很简单,对吧?

角色爆炸

即使我们解决了这个问题,RBAC 也存在扩展问题。即使在一个角色定义明确、控制良好的完美组织中,这种情况也只是暂时的。角色不会永远存在,也不会保持静止。在这种情况下,角色可能不会激增,但它们可能会发生变化,这就要求角色功能或目的的每次变化都与角色后端的根本转变相伴而生,如代码和资源访问所表示的那样。这意味着您的业务与 API 是单向耦合的,从而导致效率低下以及可扩展性和可扩展性问题。

此外,RBAC 还会增加安全态势的成本和复杂性。当您根据谁需要访问资源来定义资源安全性时,您采取的是一种将代码与组织耦合的定向方法。这需要有人来管理问题,有人不断审查角色及其访问权限,有人确保新员工有适当的角色分配。随着时间的推移,这些成本可能会相当可观,虽然这样的成本在 20 人的初创公司中可能很容易处理,但数百或数千人的大型组织很快就会发现,通过基于角色的模型确保安全的后勤和管理成本相当高昂——有时甚至高得令人望而却步。

什么是基于属性的访问控制 (ABAC)?

作为 RBAC 的替代方案,还有基于属性的访问控制。与根据访问资源的人员的角色限制访问权限的 RBAC 不同,ABAC 专门通过创建属性来寻求控制。这些属性不仅限于正在访问的资源或访问该资源的人员的角色。事实上,这些属性可以附加到网络上的任何元素,无论其来源、类型或结构如何。

例如,我们可以用下列方式附加属性:

  • 用户:属性,例如用户类型(员工、普通用户、管理员)、IP 地址或用户是否属于网络内部。这些属性也可能来自用户身份验证本身,例如指定身份验证强度或身份验证的来源。请注意,用户属性本质上是角色从最终区分因素转变为被视为属性的一部分。
  • 资源:资源是否具有特权、是否需要高凭证、是否是新的、或者是否早于某个日期。
  • 请求:请求的数据,请求的时间,或已发出了多少个此类请求。
  • 环境:日期、环境相对负载、流量级别等。

这并不是一份详尽的清单。从本质上讲,属性可以附加到网络中的几乎任何事物上,然后用作控制交互的限制元素。

ABAC 的工作原理

让我们看看 ABAC 的工作原理以及它如何解决上述角色爆炸问题。假设您有一位销售代表试图访问客户订单信息。他们具有以下属性,这些属性包含在访问令牌中:

access_token {
type: sales_rep;
department: sales;
user_id: 123;
admin_level: 2;
exp: <some timestamp>;
}

当销售代表调用系统检索订单信息时,系统会评估他们是否具有必要的权限。如果我们使用 ABAC,我们可以根据这些特定属性定义规则来接受或拒绝请求。例如,可能只有admin_level3 或以上的用户才被允许查看订单详细信息。此外,与该字段相关的规则user_id可以确保销售代表只能查看与他们分配的客户相关的订单。

此类属性也可以自动分配,以遵循组织的行为。例如,假设销售代表创建了一个新用户。系统会使用与created_by销售代表相匹配的字段来更新此新客户资料,从而将此客户绑定到特定销售代表的帐户,并防止未经授权的用户访问。

user {
user_id: 00918;
created_by: 123;
orderPlaced: yes;
}

更进一步,我们可以将销售代表的用户 ID 添加到每个订单号前面,如下所示:

orderID {
orderNumber: $incrementOrder;
prepend: created_by;
}

这将为该用户下达的与销售代表关联的订单生成一个类似于“123-00011”的订单号。从这里,我们可以确保销售代表只能访问带有此前缀值的订单,而不能查看与其他销售代表关联的订单。

这消除了一个客户访问另一个客户的订单的风险,而 RBAC 可能无法很好地处理这种风险。它还提供了一种动态调整特定权限的方法,并避免了角色爆炸的可能性。

为 API 设计 ABAC

现在我们已经了解了 ABAC 是什么样子的,让我们看看在为 API 设计 ABAC 时应该考虑哪些设计因素。

考虑设计属性

由于我们所有的控制权都掌握在属性本身,而不是与这些属性交互的用户手中,因此 API 提供商应该认真考虑应该使用哪些具体属性。与角色不同,角色由组织结构和与系统交互的人员的实际情况明确设定,而属性则更加不透明。它们很大程度上取决于提供商的发现。

安全数据

寻求基本访问控制的 API(尤其是处理少量数据的 API)不应仅仅因为存在工具就将 ABAC 视为构建高度详细系统的机会。对于锤子来说,所有东西看起来都像钉子 — 提供商应考虑保护其服务所需的最少属性,并从这种理解出发开始设置其安全态势。

授权流程

授权流程应允许客户端检索带有属性的访问令牌并将其发送到 API。例如,当用户发送请求时,客户端会将用户重定向到身份系统进行身份验证,并发出包含属性的令牌。然后,该令牌将发送到 API。然后,API 会验证来自身份系统的令牌,信任它们并使用它们的属性。下图描述了这种情况。

使用令牌进行基于属性的访问控制的授权流程。

使用令牌进行基于属性的访问控制的授权流程。

同样,应该有一个通过属性更新和超时来撤销访问权限的计划。属性不是永久的,就像授权流程一样,应该可以随着需求和访问级别的变化而被撤销或更新。因此,重要的是不仅要考虑在给定属性的情况下,流程现在是什么样子,还要考虑它们可能是什么样子,以及提供商如何控制这些属性来控制这样的环境。

基于代币的架构实现 ABAC

特定的架构风格,例如 GraphQL

最终,属性将成为控制 ABAC 方法的核心系统,因此,应以与密钥或令牌相同的安全姿态和考虑来对待属性 – 这包括充足的静态和传输加密、跟踪属性、采用合理的弃用模式等。实现这样的架构需要采用灵活而强大的集成解决方案。

值得庆幸的是,OAuth 2.0等解决方案是强大的访问控制解决方案,允许大规模高水平的控制和效率,使得 ABAC 的采用相对容易上手。

使用 ABAC 进行 API 授权

ABAC是一种比 RBAC 更强大的方法,在可扩展性和可伸缩性方面具有显著优势。然而,采用 ABAC 确实需要更大的分离度和更复杂的流程。对于某些 API,这可能过于复杂,带来管理问题,而且具有讽刺意味的是,由于管理复杂且需要跟踪更大的系统,它本身也存在扩展问题。

然而,通过充分的规划,并结合跟踪、更新、撤销和弃用计划,ABAC 确实可以用来构建一个非常安全的系统。

原文地址:https://nordicapis.com/how-to-implement-attribute-based-access-control-for-apis/

#你可能也喜欢这些API文章!