关于权限系统的一些思考

开始

权限系统无非是解决两个问题,Authentication(认证-你是谁)和 Authorization(授权-你能干什么)。

Authentication

认证的问题,很好理解,就是根据用户的身份凭据,计算出这个用户的身份信息。

而身份凭据,常见有 Token 和 Session,还有 Permanent Token(永久令牌)、Application password(应用专用密码)等。

这里可以延伸聊一下登录问题,其实登录不应该算作 Authentication 范畴,登录只是一个 Action,用于换取身份凭据的动作。没有登录这个工作,换种方式颁发身份凭据,难道权限系统就不能工作了吗?

Authorization

Authorization 又可以划分为三个问题来解决:

  • 分配:赋予谁什么权限;
  • 解决/计算:计算谁有什么权限;
  • 判断:判断谁是否有某个权限;

分配

分配要考虑的问题有两个,一个是谁、一个是目标。因此分配要解决的问题就是:要给谁在什么目标上分配什么权限。

给谁?比如用户、用户组等,我们称为 Owner

什么目标?权限分配一定要有一个附着点,比如项目、公司、组织等,我们称为 AuthTarget

什么权限?为了分配上的方便,我们常常把一堆权限集称为 角色,角色的作用仅仅是为了分配上的简洁,一般不用来做判断,什么原因,下文会解释。

我们一般推荐权限系统是模块独立于业务系统的,很简单,权限系统本来就是业务不相关的。我们只要将权限系统的 AuthTarget 和业务系统的资源做关联,就能驱动业务系统完成权限工作,而这个关联行为是权限系统关联业务系统,还是业务系统关联权限系统,或是单独关联,仁者见仁,智者见智。

解决

计算一个 Owner 有什么权限,并缓存起来。

这点主要是为了性能的考虑,如果在判断的时候再去计算 Owner 的权限,必将大大拖累业务系统的性能,而且一个 Owner 的权限大部分时间内都是不变的,因此缓存命中率特别高,特别适合缓存。

缓存的 Key 的是 Owner,Value 包括 权限 + AuthTarget。

判断

判断一个 Owner 是否有权限访问资源。

判断分为前端和后端,而判断的前提就是依赖 解决 中缓存的用户权限。

为什么不用 角色 来判断 Owner 是否能访问资源呢?如果诸多资源都用一个角色 判断,不方便扩展和拆分,更严重的是,随着时间推移,常常出现自己都预想不到的越权行为,因为到处都是基于某个角色的判断。那么我多定义一些角色呢?额。这不就变成了权限判断?

直接使用权限进行判断,可以为用户提供更精细的权限控制。安全系统设计的一个重要原则是“最小权限原则”(Principle of Least Privilege),即应尽可能只授予用户完成任务所需的最低权限。通过直接基于权限判断,可以更加严格地控制用户权限的分配,减少误授权的可能性。

posted @ 2024-10-26 08:57  JMCui  阅读(65)  评论(0编辑  收藏  举报