系统权限设计 - 基本概念和思路

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 权限系统的设计几乎是每个系统都必需的模块,最近对系统的权限设计有一些心得体会。遇到过一些坑,也有一些思考,所以想写下来分享给大家。本文的目的是帮助大家理清楚权限设计中的一些基本概念,提供常用的权限系统设计思路。

权限系统的设计几乎是每个系统都必需的模块,最近对系统的权限设计有一些心得体会。遇到过一些坑,也有一些思考,所以想写下来分享给大家。


本文的目的是帮助大家理清楚权限设计中的一些基本概念,提供常用的权限系统设计思路。


首先,我们抛出一个案例,读者可以想一想如果自己来设计权限系统,如何满足这个需求?

需求描述:

在一个大学里,有许多人。学生即将进行期末考试。对于某个期末考试的试卷,有以下权限管理需求:

  • 在整个过程,该课程的老师全程可以查看试卷
  • 在考试中,该课程的监考老师可以查看试卷
  • 在考试中,该课程的学生可以查看和写入自己的试卷
  • 在考试后,该课程的老师可以写入试卷
  • 在考试后,该年级的教务主任可以查看这个年级所有课程的试卷
  • 在整个过程,打扫清洁的阿姨不能查看/写入试卷
  • 在整个过程,校长可以查看任何试卷

备注:考试过程分为考试前、考试中、考试后。一个人可能有多个角色。

UML图:


认证与授权


系统的权限控制可以分为两部分:认证和授权。两者是相对独立的概念,把它们拆开有助于我们更好地理解权限系统的设计。

认证 Authentication

所谓认证,就是判断你是不是你本人。通俗地说,就是我们系统中常见的“登录”这一步。这个验证的手段和技术有很多种,比如:表单验证、HTTP Basic验证、基于cookie的remember-me、OAuth2、甚至是指纹验证等等都是可以的。

关于各种认证方式的技术细节本文就不细讲了,这部分不在本文重点。读者只需要知道的是,权限控制的第一阶段就是认证,如果认证通过了,就说明用户登录进了系统。至于后续的各种业务的权限控制,就不归认证管了。


授权 Authorization

认证不管业务的权限控制,那谁来管呢?那就是授权了。也就是本文要讨论的重点。

首先我们需要思考一个问题:我们系统的权限设计应该有一个什么大的目标?我认为是兼顾“灵活”和“易管理”。也就是说,我们的权限设计应该能够灵活应对变化,包括用户的变化、业务权限要求的变化。但同时,它又应该比较容易管理,这样才能够让我们的权限足够清晰,不至于混乱。

所以基于上述目标,我认为权限系统的设计应该有以下三个原则:

够用就行

这里强调的是权限系统应该在满足需求的前提下尽量简单,不要过度设计。比如对于我的个人博客网站来说,只需要有我自己一个用户,那就没必要做很复杂的权限控制。

粒度适中

这里的“粒度”指的是权限的粒度。一个权限如果粒度过粗,就会导致多个业务场景使用一个权限,灵活性很差;而权限如果粒度过细,就会让权限变多,难以管理。

推荐以业务操作为权限的粒度。一个业务操作对应一个权限。业界也有DDD(领域驱动设计)等工具来帮助更好地划分业务。

比如我们上述案例中,虽然老师和学生都有“写入试卷”的操作,但其实通过理解业务,我们可以把它分为“答题”和“打分”。

那API与业务操作是一一对应的吗?多数业务场景应该是的,但也有例外。比如发微信朋友圈,就需要at人,上传图片、已经真正保存自己要发送的内容这三个操作组成“发朋友圈”这个业务,也就对应了三个业务。

这里根据笔者的实践来看,更推荐使用一个权限,可以访问这三个API。或者三个权限,分别对应相应的API,但有“权限组”的概念,把它们三个加进一个权限组,实际分配权限的时候就分配这个权限组就行了。不推荐仅仅只是三个权限分别控制三个API。

尽量使用白名单

这个是众所周知的安全原则之一。我们在实现权限系统的时候,应该尽量使用白名单,而不是黑名单。比如:有xx权限的人才能进行xx业务。而不是:没有xx权限的人就能进行xx业务。


主流的权限设计模型

权限设计是一个不容易的事,但基本上所有的系统都需要权限设计。实际上,业界已经有一些主流的权限设计模型了。这里只简单介绍一些常用的。

ACL

访问控制列表,多用于简单的权限控制。尤其在网络流量控制那块用得很多,很少用在业务系统上。

RBAC

基于角色的访问控制(Role-Based Access Control),权限与角色相关联,用户通过分配适当角色而得到这些角色的权限。也是业界最主流的权限设计模型。RBAC不能很好地检查与“数据状态”相关的权限,比如“试卷在考试前,只有老师能查看”这种需求。需要自己把角色写死,然后在代码里写逻辑检查。

ABAC

基于属性的访问控制(Attribute-Based Access Control),为了解决上述问题,业界有一种叫ABAC的解决方案。通过写动态的DSL来判断数据的状态,通过一些自定义的语法来做权限控制。

ABAC有时也被称为PBAC(Policy-Based Access Control)或CBAC(Claims-Based Access Control)。ABAC通常用于平台级的系统。比如AWS、阿里云等“云提供商”,他们有海量的资源、角色,需要很灵活的权限管理系统。

ABAC的实现成本很高。管理上也比较复杂。

示例(阿里云的RAM):

{
    "Version": "1",
    "Statement":
    [{
        "Effect": "Allow",
        "Action": ["oss:List*", "oss:Get*"],
        "Resource": ["acs:oss:*:*:samplebucket", "acs:oss:*:*:samplebucket/*"],
        "Condition":
        {
            "IpAddress":
            {
                "acs:SourceIp": "42.160.1.0"
            }
        }
    }]
}
复制代码


权限设计演进

本着上面提到的够用就行的原则,权限系统不应该过度设计。我们可以根据权限需求从简单到复杂,大概分为三类:

  • 只需要一个管理员,管理所有内容,比如个人博客网站。
  • 只有一些用户和角色,且角色所拥有的权限相对稳定。适用于绝大多数系统。
  • 有很多的用户和角色,且角色的权限很容易变化。平台级系统,如AWS。

因为第二种适用于绝大多数日常开发的项目,所以后面主要讨论的是第二种。如果是第三种的话,推荐基于ABAC开发出一套定制化的权限系统。


区分Access与Validation


先来澄清一些这两个名词的概念:

  • Access:我能不能call这个API,与数据无关,可以在网关这一层就拦截。
  • Validation:我能Call这个API,但到底有没有相应的权限,与业务数据有关,可以写Validator来验证,推荐放在最下层service。

很多第一次做权限设计的朋友,容易把他两搞混,设计出来的权限就可能看起来很混乱。

我们再来分析一下案例,就拿“读取试卷”这个业务操作来说,我们可以有一个Access叫做READ_PAPER,把它赋予给学生、老师、监考老师、教务主任、校长这几种角色。代表他们可以call这个业务API。而进到具体的验证逻辑的时候,就需要去查数据库取出试卷的状态、对应的班级、监考老师ID等等信息,通过Validation去验证这些数据,当前角色是否可以访问。

下篇文章会更具体地从前后端的视角、权限的粒度和代码层面来给出一套推荐的权限设计方案。

相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
目录
相关文章
|
XML JSON 算法
【软件设计师备考 专题 】编写内部设计文档:构件划分图和接口
【软件设计师备考 专题 】编写内部设计文档:构件划分图和接口
49 0
|
6月前
|
存储 缓存 监控
《优化接口设计的思路》系列:第二篇—接口用户上下文的设计与实现
大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 作为一名从业已达六年的老码农,我的工作主要是开发后端Java业务系统,包括各种管理后台和小程序等。在这些项目中,我设计过单/多租户体系系统,对接过许多开放平台,也搞过消息中心这类较为复杂的应用,但幸运的是,我至今还没有遇到过线上系统由于代码崩溃导致资损的情况。这其中的原因有三点:一是业务系统本身并不复杂;二是我一直遵循某大厂代码规约,在开发过程中尽可能按规约编写代码;三是经过多年的开发经验积累,我成为了一名熟练工,掌握了一些实用的技巧。
51 0
|
24天前
|
编解码 缓存 数据库
【软件设计师备考 专题 】编写内部设计文档:屏幕设计和数据库设计
【软件设计师备考 专题 】编写内部设计文档:屏幕设计和数据库设计
62 0
|
23天前
|
传感器 运维
【软件设计师备考 专题 】编写外部设计文档:系统配置图和关系图
【软件设计师备考 专题 】编写外部设计文档:系统配置图和关系图
50 1
|
2月前
|
安全 程序员 数据安全/隐私保护
终于有篇文章把后管权限系统设计讲清楚了
【2月更文挑战第1天】在常用的后台管理系统中,通常都会有权限系统设计,以用于给对应人员分配不同权限,控制其对后管系统中的某些菜单、按钮以及列表数据的可见性。
65 2
终于有篇文章把后管权限系统设计讲清楚了
|
6月前
|
存储 缓存 Java
《优化接口设计的思路》系列:第四篇—接口的权限控制
大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 作为一名从业已达六年的老码农,我的工作主要是开发后端Java业务系统,包括各种管理后台和小程序等。在这些项目中,我设计过单/多租户体系系统,对接过许多开放平台,也搞过消息中心这类较为复杂的应用,但幸运的是,我至今还没有遇到过线上系统由于代码崩溃导致资损的情况。这其中的原因有三点:一是业务系统本身并不复杂;二是我一直遵循某大厂代码规约,在开发过程中尽可能按规约编写代码;三是经过多年的开发经验积累,我成为了一名熟练工,掌握了一些实用的技巧。
66 0
《优化接口设计的思路》系列:第四篇—接口的权限控制
|
10月前
|
XML JSON 前端开发
史上最强的权限系统设计攻略(下)、ABAC在复杂场景下的实现思路
史上最强的权限系统设计攻略(下)、ABAC在复杂场景下的实现思路
865 0
|
11月前
|
Shell
操作系统—概述思维导图梳理结构及知识点
操作系统—概述思维导图梳理结构及知识点
101 0
|
12月前
|
监控 安全 前端开发
权限系统就该这么设计,yyds
权限系统就该这么设计,yyds
|
前端开发
前端学习案例9-二叉树的概念和特性2
前端学习案例9-二叉树的概念和特性2
52 0
前端学习案例9-二叉树的概念和特性2