在软件工程中,就像其他很多领域一样,设计和实现一个授权系统有很多种方法。授权系统为应用增加了一个安全和验证的层级,让你可以控制谁能访问哪些资源,确保只有授权的用户才能看到特定的内容。

授权显然是大多数系统中的关键功能之一,所以在设计系统时,这部分真的需要认真对待。

你可以自己发明一种授权机制,但利用利用他人已有的解决方案往往能省下不少时间和精力。

对于SaaS产品,常见的授权设计主要有以下三种。每种方案都有它的优点和不足,所以它们各自适用的场景也不同。

首先需要说明的是,这些授权模型都不是一成不变的。

这里讨论的每个例子仅仅是实现这种授权方式的一种可能方法。

访问控制列表

ACL(Access Control List,访问控制列表)可能是最简单的授权模型了。

它通过维护一个用户列表,来记录哪些用户被允许执行特定操作。

对于那些不需要特别细粒度权限控制的简单系统,ACL 是个有效的授权方式。

举个例子,假如你在系统里实现了基本的 ACL 授权,下面这个图表就展示了你的数据库架构可能的样子:

SaaS产品的三种常见授权架构设计:ACL、RBAC和ABAC_数据库

图中的标签是“用户”和“权限”。一个用户可以有0个或多个权限。使用这种设计,权限是比较随意的,用户与权限之间的连接也很灵活。

ACL 的主要优势在于它的简单性。对于很多系统来说,实施和维护起来都相对快速且成本低。如果你的系统需求不复杂、规模较小,采用这种设计确实挺好,因为它不需要太多复杂的功能。

但正因为 ACL 简单,最大的缺点恰恰是它的简单性。随着系统的成长和扩展,ACL 的简单性可能会变成问题。

因为权限是直接和特定用户关联的,所以当有新用户加入时,可能得手动给他们分配权限。而且,如果你需要为所有现有用户添加或删除权限,这项工作也会变得很繁重。

当你的系统需求超出了简单ACL的能力时,你可能就需要升级到更复杂的设计模式,比如 RBAC(基于角色的访问控制)。

基于角色的访问控制

RBAC(Role-Based Access Control,基于角色的访问控制)比ACL更复杂,但也更强大、更灵活,特别适合某些特定的场景。

通过RBAC,你可以为用户分配角色,然后根据这些角色来决定他们应该被允许访问的内容。

举个例子,你可以设置一个“财务”角色,授予该角色访问系统中财务部分的权限,或者设置一个“支持”角色,授予其访问帮助台相关内容的权限。

角色的具体工作方式取决于你的实现需求。你可以让一个用户拥有多个角色,也可以根据具体场景限制用户只能拥有一个角色。

下面这个图表展示了如果你实现了 RBAC,数据库架构可能会是什么样子:

SaaS产品的三种常见授权架构设计:ACL、RBAC和ABAC_数据库_02

在这种设计中,有三个主要元素:“用户”、“角色”和“权限”,它们之间通过中间表来建立关联。

这种结构允许一个用户关联多个角色,每个角色则可以分配多个权限。权限通常是相对广泛的,比如“查看报告”或“编辑用户”,而不是针对单个资源的细粒度权限(这更属于 ABAC的领域,稍后会提到)。

RBAC有几个显著的优点,首先是实现的相对简单性。虽然比起简单的ACL,RBAC的设计稍微复杂一些,但它依然比ABAC和其他高级授权模型要简单得多。这使得它更容易实现,且长期的维护和支持成本较低。

RBAC的简单性也表现在日常使用中。因为权限都是通过角色绑定的,你在为新用户设置访问权限时,通常只需要为其分配合适的角色即可,而不需要记住复杂的规则。

这和ACL 不同,ACL中可能需要手动修改用户权限。

RBAC的一个主要风险是可能会出现所谓的“角色爆炸”问题。当系统需要越来越细粒度的控制时,通常的解决方案是创建更多的角色。

这会导致两个问题:

  1. 多角色管理的复杂性:如果系统允许用户同时拥有多个角色,为了满足各种权限需求,可能会创建大量新角色,每个角色可能只有少量的权限。这会增加管理和维护的复杂性。
  2. 重复角色的增多:如果系统不允许用户拥有多个角色,那么为了满足不同用户的需求,可能会导致创建大量几乎相同但又稍有不同的角色。这不仅让系统难以管理,还增加了角色的重复和冗余。

这两个问题都不理想,正是因为RBAC在处理细粒度权限方面的局限性。这也意味着,当系统需要更精细的权限控制时,RBAC可能不再是最佳选择,可能需要考虑更复杂的模型,如属性基访问控制(ABAC)。

基于属性的访问控制

ABAC(Attribute-Based Access Control)是一种访问控制模型,它根据用户、资源、环境等属性来决定是否授予访问权限。

与传统的授权模型(如 ACL 和 RBAC)相比,ABAC 提供了更细粒度的权限控制,允许基于上下文信息进行动态决策。

1.核心概念

ABAC 的核心在于通过属性来控制访问权限。这些属性可以来自于多种来源:

  • 用户属性:用户的身份、角色、组织部门、职位等信息。
  • 资源属性:资源的类型、分类、所有者、敏感性等级等信息。
  • 环境属性:访问的时间、地点、设备类型等外部因素。

这些属性用于制定访问控制策略,决定用户是否可以访问特定的资源。

2.如何工作

在 ABAC 模型中,授权决策是基于一组定义好的访问控制策略,这些策略通常使用逻辑表达式来描述。策略的形式可以是规则、条件或逻辑运算符,结合了用户、资源和环境的属性。例如,策略可能会规定:

  • “只有当用户属于‘财务部门’并且访问的资源是‘财务报告’时,用户才被允许访问该报告。”
  • “在工作时间内(上午9点到下午5点),用户才能访问敏感信息。”

3.数据库架构示例

实现ABAC时,数据库通常包含以下表:

  • 用户表:存储用户的基本信息和属性。
  • 角色表(可选):如果系统中使用角色,还需记录角色与属性的关系。
  • 资源表:记录系统中所有资源的属性。
  • 环境表:记录与环境相关的数据,如时间段、地理位置等。
  • 策略表:定义访问控制策略,包括属性和条件。

下面是一个可能的数据库架构,展示了如何实现ABAC:

SaaS产品的三种常见授权架构设计:ACL、RBAC和ABAC_数据库_03

ABAC非常灵活,但也充满了主观性。因为授权评估是基于系统中定义的属性,没有一个通用的架构适用于所有情况。

在上面的例子中,你可以看到有“用户”以及“角色”、“区域”和“客户”,还有客户与区域以及数据的关联。

在这种设计下,你可能需要对用户访问客户数据的权限进行控制,比如在以下条件都满足时才允许访问:

  • 用户具有管理员角色
  • 用户具有客户支持角色
  • 用户与数据所属的客户在同一区域
  • 数据未被标记为敏感

这些条件基于对象的属性,而不是具体的访问记录或权限,这正是 ABAC 的核心特征。

虽然这种设计的实现难度更大,但它的强大之处在于,对于复杂业务逻辑的大型组织来说,ABAC通常是不可或缺的。

ABAC的优势在于它的灵活性。通过基于属性来创建访问策略,组织可以对谁能访问什么资源进行非常细致的控制。而且,ABAC 的扩展性也非常好,因为当新用户加入时,你只需为他们分配合适的属性,而无需修改现有的策略。这确保了他们可以访问所需的资源来执行工作。

然而,ABAC也有其局限性。要决定是否采用 ABAC作为你的授权设计,关键在于权衡成本——不仅是财务上的投入,还包括时间、实现的复杂度,以及后续维护的难度。

由于 ABAC的设计较为复杂,如果你从零开始实现,可能会耗费更多的精力。

总结

以上是三种不同的 SaaS 应用授权实现模型。每种模型都有自己的优缺点。

  • ACL:简单直观,适用于小型系统。它易于实现,但当系统规模扩大时,权限管理可能变得繁琐,扩展性较差。
  • RBAC:通过将权限与角色关联,解决了ACL的一些局限。它适合小型到中型系统,尤其是那些超出了ACL能力的系统。然而,RBAC在处理细粒度权限时有所不足,可能会面临“角色爆炸”的问题。
  • ABAC:提供了更高的灵活性和细粒度的权限配置,适合复杂的业务需求。尽管ABAC能够满足高复杂度的授权需求,但其实现和维护的复杂性以及成本也较高。