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

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

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


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


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

需求描述:

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

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

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

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去验证这些数据,当前角色是否可以访问。

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

相关实践学习
通义万相文本绘图与人像美化
本解决方案展示了如何利用自研的通义万相AIGC技术在Web服务中实现先进的图像生成。
目录
相关文章
|
Go 数据库
Golang 语言编写 gRPC 实战项目
Golang 语言编写 gRPC 实战项目
296 0
|
Ubuntu Unix Linux
Ubuntu 开机启动脚本配置
本文基于Ubuntu 20.04 LTS版本用实例来讲解如何配置开机自启动服务。
1321 1
Ubuntu 开机启动脚本配置
|
测试技术 数据库 uml
【软件工程与UML】第2章 用例图、用例文档、活动图 -- 系统的功能需求建模
【软件工程与UML】第2章 用例图、用例文档、活动图 -- 系统的功能需求建模
1185 0
【软件工程与UML】第2章 用例图、用例文档、活动图 -- 系统的功能需求建模
|
容器 Perl Kubernetes
深入 Kubernetes 网络:实战K8s网络故障排查与诊断策略
本文介绍了Kubernetes网络的基础知识和故障排查经验,重点讨论了私有化环境中Kubernetes网络的挑战。首先,文章阐述了Kubernetes网络模型的三大核心要素:Pod网络、Service网络和CNI,并强调了其在容器通信和服务发现中的作用。接着,通过三个具体的故障案例,展示了网络冲突、主节点DNS配置更改导致的服务中断以及容器网络抖动问题的解决过程,强调了网络规划、配置管理和人员培训的重要性。最后,提到了KubeSkoop exporter工具在监控和定位网络抖动问题中的应用。通过这些案例,读者可以深入了解Kubernetes网络的复杂性,并学习到实用的故障排查方法。
148624 19
|
存储 缓存 NoSQL
Redis多级缓存指南:从前端到后端全方位优化!
本文探讨了现代互联网应用中,多级缓存的重要性,特别是Redis在缓存中间件的角色。多级缓存能提升数据访问速度、系统稳定性和可扩展性,减少数据库压力,并允许灵活的缓存策略。浏览器本地内存缓存和磁盘缓存分别优化了短期数据和静态资源的存储,而服务端本地内存缓存和网络内存缓存(如Redis)则提供了高速访问和分布式系统的解决方案。服务器本地磁盘缓存因I/O性能瓶颈和复杂管理而不推荐用于缓存,强调了内存和网络缓存的优越性。
1342 47
|
10月前
|
人工智能 自然语言处理 大数据
【阿里云】通义灵码支持 DeepSeek R1 和 V3、Qwen2.5 模型
最近参加了阿里云通义灵码模型切换体验活动,深入体验了DeepSeek R1、V3和Qwen2.5模型。通过简便的注册流程,我轻松参与并测试了不同模型在自然语言处理、计算效率等方面的表现。操作界面清晰,模型切换流畅,性能出色,尤其在大数据处理时表现优异。此外,还获得了Cherry机械键盘等精美奖品。这次体验让我对AI技术有了更深的理解,强烈推荐给AI开发者和爱好者。[立即体验](https://t.aliyun.com/BLkE2b2m)
|
消息中间件 Java Linux
得物面试:什么是零复制?说说 零复制 底层原理?(吊打面试官)
尼恩,40岁老架构师,专注于技术分享与面试辅导。近期,尼恩的读者群中有小伙伴在面试一线互联网企业如得物、阿里、滴滴等时,遇到了关于零复制技术的重要问题。为此,尼恩系统化地整理了零复制的底层原理,包括RocketMQ和Kafka的零复制实现,以及DMA、mmap、sendfile等技术的应用。尼恩还计划推出一系列文章,深入探讨Netty、Kafka、RocketMQ等框架的零复制技术,帮助大家在面试中脱颖而出,顺利拿到高薪Offer。此外,尼恩还提供了《尼恩Java面试宝典》PDF等资源,助力大家提升技术水平。更多内容请关注尼恩的公众号【技术自由圈】。
得物面试:什么是零复制?说说 零复制 底层原理?(吊打面试官)
|
存储 监控 安全
深入理解RBAC权限系统
RBAC(Role-Based Access Control)是一种访问控制模型,其核心概念是基于角色的权限分配。该模型的设计目标是简化对系统资源的访问管理,提高系统的安全性和可维护性。
2750 2
深入理解RBAC权限系统
|
SQL Java 数据库连接
【Java】已解决java.sql.SQLRecoverableException异常
【Java】已解决java.sql.SQLRecoverableException异常
2066 0
|
测试技术 uml 开发者
如何画出规范的 UML 用例图
如果你在做设计过程中有一些困惑,如:不会找用例、两个用例图分不清楚、不知道自己画的对不对。那么希望本文能帮助厘清上面几个问题,真正掌握用例图,在后面的设计中能运用的得心应手。
如何画出规范的 UML 用例图