~# n0tr00t Security Team

一种通用型的权限系统设计

30 Sep 2018 - h3l

[+] Author: h3l
[+] Team: n0tr00t security team 
[+] From: https://www.n0tr00t.com
[+] Create: 2018-09-30

先简单看一下简单的表结构以及表关系。

                               +----------+  parent_id & child_id    +--------------+
                               | Relation | ------------------------ | Organization |
                               +----------+                          +--------------+
                                                                       |
                                                                       | org_id
                                                                       |
                               +----------+  user_id                 +--------------+
                               |   User   | ------------------------ | UserPosition |
                               +----------+                          +--------------+
                                                                       |
                                                                       | group_id
                                                                       |
+-----+  service_id & api_id   +----------+  group_id & service_id   +--------------+
| Api | ---------------------- | Service  | ------------------------ |    Group     |
+-----+                        +----------+                          +--------------+

表解释

概述

上述的那么多表,其实只是解决了一个问题『一个人什么范围能做什么事情』。

用户相关

即权限系统中的用户,并无复杂概念

组织相关

现实生活中的组织架构是一个类似树形的不规则结构,如下图所示

                                  +----------+
                   +------------- |   root   | ------+
                   |              +----------+       |
                   |                |                |
                   |                |                |
                   v                v                |
                 +----------+     +----------+       |
  +------------- |  mid_a   |     |  mid_b   |       |
  |              +----------+     +----------+       |
  |                |                |                |
  |                |                |                |
  v                v                v                v
+----------+     +----------+     +----------+     +----------+
| bottom_a |     | bottom_b |     | bottom_c |     | bottom_d |
+----------+     +----------+     +----------+     +----------+

如果是存储树形结构,第一反应可能是在每个节点记录一个 parent_id。这是最简单的做法,但是在查询某个节点的所有子节点的时候却是效率最差的做法。

这里我们采用的方法是单独拿一张关系表记录父节点到所有子节点的数据。这样做的好处是查询效率非常高,只是在插入数据的时候稍微慢一点,但是考虑到我们的应用是读大于写,所以这样做并无不妥。按照上述说法,则可以用下表表示下图。

                                  +------+
                   +------------- | root | ------+
                   |              +------+       |
                   |                             |
                   |                             |
                   v                             |
                 +----------+                    |
  +------------- |  mid_a   |                    |
  |              +----------+                    |
  |                |                             |
  |                |                             |
  v                v                             v
+----------+     +----------+                  +----------+
| bottom_a |     | bottom_b |                  | bottom_d |
+----------+     +----------+                  +----------+
父节点 子节点
root mid_a
root bottom_a
root bottom_b
root bottom_d
mid_a bottom_a
mid_a bottom_b

tip: 如果为了方便,可以为每个节点插入一条父节点和子节点均为自己的记录。

该方法并非独创,详细的分析该方法以及与其他方法的对比可参见https://www.slideshare.net/billkarwin/models-for-hierarchical-data

群组相关

在群组这部分的设计中,包含了五张表。但是关键的概念仅为 Api, Service, Group, 其实这样设计会稍显复杂。那我们为什么要这样设计呢?

最重要的原因是将开发与产品/运营间有效的隔离开。

Api 表记录的是系统中所有的接口,这是开发需要维护的部分。

Service 表记录的是系统中的功能点,这是需要产品/运用同开发共同维护的部分

Group 表记录的是系统中的群组,这是需要产品维护的部分,同时产品需要维护群组与功能点的关系。

ps: Api 表中的 app_nameurl_name 是为了保证在不同系统中相同的 url_可能会冲突的情况

pss: 🤔仔细想想,Api 表中的 api 是不是可以偷懒的整个一个系统只用同一个呢?甭管你有多少接口,全部一把梭,都用同一个 api。当然可以了,只要能满足需求, api 怎么记录完全看你自己,这也是本系统灵活的原因。

n more thing