---
URL: "/zh-CN/blog/2025-02/abac.html"
LLMS_URL: "/zh-CN/blog/2025-02/abac.md"
lastUpdated: true
commentabled: true
recommended: true
title: "权限模型-ABAC模型"
description: "权限模型-ABAC模型"
date:

pageClass: "blog-page-class"
---

---
lastUpdated: true
commentabled: true
recommended: true
title: 权限模型-ABAC模型
description: 权限模型-ABAC模型
date: 2025-02-08 10:00:00
pageClass: blog-page-class
---

# 权限模型-ABAC模型 #

## ABAC 的概念 ##

ABAC（Attribute-Based Access Control）基于属性的访问控制的权限模型，是一种细粒度的权限控制模型，通过对请求中的各种属性进行分析和匹配，`实现对权限的灵活的、动态的控制`。

## ABAC 的组成部分 ##

- **主体（Subject）**: 发起访问资源请求的用户或实体（如应用程序、系统）。主体具有多种属性，例如角色、身份、部门、敏感级别、创建时间。

>💡Tips: 实际中可能就是存储用户信息的记录表、发起请求的设备信息等。

- **对象（Object）**: 被访问的资源或数据。对象可以是文件、数据库表、API 接口等，同样具备多种属性，如文件名、文件类型、敏感级别、创建时间等。

- **操作（Action）**: 用户试图对资源的操作 ，例如”读”、“写”、“创建“、”删除“、”复制“等。

- **环境（Environment）**: 外部环境属性，如访问时间、地点、网络状态、安全级别等，用于动态调整访问策略。

- **策略（Policy）**: 定义允许或拒绝的访问的规则。策略基于主体、对象、操作和环境属性的组合，通过逻辑规则决定是否允许访问。

>💡Tips: 策略如何定义？
> 一般来说 策略都有自己的语法设计，以 XML、JSON 这种形式去描述一个访问策略如何构成。
> 策略也是访问规则，本文中不再做区分。

## ABAC 工作的基本原理 ##

ABAC 的基本原理是：系统根据主体、对象、操作、环境的属性，以及预定义的策略，动态生成访问决策。

### 简单流程 ###


``` mermaid
        sequenceDiagram
        participant User
        participant 访问控制系统
        User->>访问控制系统: 发起请求(包含主题、对象、操作)
        访问控制系统->>访问控制系统: 匹配请求中的属性与预设的的访问控制策略
        访问控制系统->>访问控制系统: 根据策略规则动态判断是否允许该请求
        访问控制系统->>User: 返回访问控制结果(允许/拒绝)
``` 

- **发起请求**: 通常一个访问请求由主体、对象（资源）、环境、操作中的一个或者多个组成。每个组成部分又有各自的属性，需要用到各个组成部分的属性，去动态构建一个访问规则。

```text
例如 中午 12 点后禁止 A 部门的人访问 B 系统这个访问规则。
中午 12 点以后：环境（时间属性）
A 部门的人：主体（身份属性）
B 系统：对象（被访问的资源）
访问: 操作
```

- **匹配属性**：在预设的访问规则库中查找与请求匹配的规则或规则集合。

- **规则评估**：根据匹配的访问规则中的具体规则来评估请求。将请求中的属性值与规则中的条件进行对比，判断请求是否满足规则中的条件。例如请求中包含了访问的时间在 12 点以后，那么访问控制系统就会对比访问时间这个属性值。

- **返回结果**：向用户返回最终的规则执行的结果。

> 💡Tips: 图中只是演示了一个大致的工作流程，实际要设计一个 ABAC 权限系统要复杂的多。
>
> 因为所有的规则条件是动态的、逻辑也是动态执行的。

## ABAC的难点 ##

试想以下场景：

- 当前文档是文档的拥有者且是拥有者才能编辑。
- 售卖的产品只能是上海地区的用户才能可见。
- 中午 12 点后禁止 A 部门的人访问 B 系统。

如果使用 RBAC 模型很难实现以上的需求。`RBAC 是静态的权限模型`，没有对象的属性动态参与计算的，所以很难实现以上场景。

> ABAC 系统非常灵活但实现比较困难。

### 属性收集和管理复杂度 ###

#### 属性管理 ####

访问规则依赖`属性`和`属性值`去构建，特别是动态属性（实时位置，时间），如何确保获取到最新的属性值。

> 💡Tips: 属性是否可以动态增加也是构建系统的一部分，例如用户属性中你增加了一项职业，那该属性的值类型和获取该值的方法如何定义也是属性管理的一个难点。

#### 数据一致性和同步 ####

分布式系统中，各种属性的数据源可能分散在不同的系统中，如何准确的、高效的获取该属性和属性值。

### 访问规则的复杂度 ###

#### 条件逻辑 ####

构建一个访问规则通常包含复杂的条件，条件可能是大于、小于、区间、地理位置等。这些条件需要仔细的定义和维护。

#### 多条件组合 ####

访问规则需要涵盖不同属性的组合条件，属性组合的数量随着属性的增加呈指数型增长。

#### 策略管理 ####

如果访问规则在数量一直增长，访问规则的生命周期（更新、删除）将变得复杂。如果其中属性的变动也会影响现有存在的访问规则。

#### 动态性 ####

ABAC进行决策时需要实时评估所有相关属性的当前值，并与策略条件进行匹配。这种评估会增加计算的开销，尤其在处理大量请求时对计算资源要求更高。

### 透明性 ###

#### 可追溯性 ####

ABAC的动态决策过程复杂，审计和跟踪某个过程中的条件匹配和组合算法变得困难。为了便于审计和问题排查，ABAC 系统通常需要记录详细的决策日志，这增加了额外的复杂性。

#### 决策透明度 ####

复杂的条件和组合逻辑使得管理员在排查和解释某个请求的决策较为困难，用户请求被拒绝可能难以理解其原因，这对系统性提出了挑战。

## ABAC 的实现 ##

### 标准实现-XACML ###

XACML 是一种基于 XML 的标准访问控制控制策略语言，用于定义和管理复杂的访问控制需求。

> 💡Tips: XACML 是 ABAC 的一个标准实现，用 XML 文件定义访问的策略集，然后提交 XACML 引擎来进行权限决策。由于这个太过复杂，这里不讲述了。有兴趣的可以看下官网XACML version 3.0。（当然还有其他标准的实现）

### ABAC 的权限系统设计的核心 ###

目前 ABAC 系统没有单独使用的，基本都是搭配RBAC （基于角色的权限模型）来使用。目前已有的类似方案如 AWS的 IAM （Identity And Access Management）也都是借鉴了 ABAC 的设计理念来实现的精细权限控制。

一个 ABAC 系统通常需要考虑以下核心的三个关键步骤：

- 属性管理：属性的定义、结构和属性值的获取。
- 访问规则：访问规则的结构化和语法定义。
- 规则编辑器：规则编辑器和规则匹配引擎。

> 💡Tips: 目前这里探讨的设计因为没有具体的场景，这里的所说的设计权做参考。顺便一提属性管理、规则编辑器、访问规则其实设计的思路和CDP系统非常相似。

### 属性管理 ###

属性有动态属性和静态属性，如性别那就是静态的，年龄、角色、地理位置这些都是动态的。

属性管理的难点是属性的定义和属性值获取。

- 属性的定义

一般来说属性的定义包括属性名、字段类型、来源（获取该属性值的方式）。

业务确认属性的范围，也就是说设计时确认了目前业务要用到哪些属性就不能进行更改（修改、删除）操作。如果是需要动态的进行属性的新增、修改就需要更抽象的灵活设计。

> 💡Tips: 如果其他的访问规则中使用了该属性，修改和删除都会影响使用该属性的访问规则。

- 属性值的获取

`属性和属性值的来源单一` 例如用户的属性就一张用户表，那直接读取用户表就好了。如果你的用户数据是分散在不同来源的，需要考虑的如何聚合数据和保证数据一致性的问题。

### 访问规则 ###

目前现在是有一些ABAC 的设计系统大多都是采用 JSON 语言描述访问规则。该 JSON 中包含了访问规则中所用到的属性、条件、操作等。示例如下：

```json
{
  "subject": {
    "role": "manager",
    "department": "finance"
  },
  "object": {
    "type": "document",
    "sensitivity": "confidential"
  },
  "action": "view",
  "environment": {
    "ip": "192.168.1.*",
    "time": {
      "start": "09:00",
      "end": "18:00"
    }
  },
  "effect": "allow"
}
```

> 💡 实际开发中根据业务场景，系统中描述JSON 中的结构语义都有自己的规范。

### 规则编辑和规则匹配 ###

ABAC 的核心部分是**如何构建一个规则编辑器和规则匹配引擎**，这个规则编辑器需要满足各种复杂条件的组合（这里的条件指的是一个条件或多个条件）。这里的条件之间的关系可能不止“且”的关系，可能还存在“或”。

一些地方描述构建规则为动态 SQL 的构建，但是这种方式需要对应的资源需要映射为数据库记录且有对应的属性存在表结构中，简单就是理解是宽表+属性。可有些属性是没办法在数据库结构中体现的如访问位置、访问时间等，这些就需要在规则匹配引擎中做设计了。

>💡Tips: 目前所说的规则编辑和规则匹配都是为了动态 SQL 的构建，这块比较有通用性（有些数据权限设计采用的就是该种思路。）。至于其他方式需要考虑具体的业务环境。

规则编辑器通常都设计成管理界面，通过界面上选取中的属性和条件构成一个JSON ，然后提交到规则匹配引擎去执行，将JSON 转换成动态 SQL，发起访问请求时去拿到访问规则构建的SQL去执行。

>💡Tips 这里的规则匹配引擎最主要的工作就是根据 JSON 中的描述的规则，动态生成一段 SQL。

## 总结 ##

事实上 ABAC 现在没有什么标准建模，借鉴ABAC 的设计思维达到你想要的基于属性控制权限就可以了。至于采用何种方式、是否搭配其他权限模型，具体业务、具体分析。
