权限控制的相关概念辨析

我们做后端开发,权限控制是绕不开的话题。几乎所有后台系统都需要权限控制模块。权限控制涉及的概念不多,但容易混淆,这里尝试简单梳理一下。为了便于大家理解,我们结合案例来加以说明。

什么是权限控制?

某个主体(subject)对某个客体(object)需要实施某种操作(operation),系统对这种操作的限制就是权限控制。
权限控制涉及三个概念:

  • **主体(subject)**:可以拥有权限的概念对象,比如 用户、角色、岗位、部门等。
  • **客体(object)**:可以被用来进行权限控制的概念对象,比如 文件、菜单、功能、操作等。
  • **操作(operation)**:主体对客体进行的访问动作,比如 读、写、执行、查询、修改、新增、删除等。

主体能够做什么,就是权限。权限可以细分为不同的能力。比如,在Linux文件系统中,文件具备读、写、执行三种能力。

要充分理解权限控制,需要仔细分辨以下几组概念。

  • 认证 和 授权
  • 访问 和 验证
  • 操作权限 和 数据权限

认证(Authentication) VS 授权(Authorization)

认证是识别操作者是谁的过程,解决Who am I的问题。
授权是识别操作者能够做什么事,解决What can I do的问题。

认证是进入系统的第一步,通常就是指系统中的“登录”这一步。认证的常见实现方式有:表单验证、Http Basic验证、OAuth2等。在做授权之前,需要先完成认证。举个例子,我要在Github中新建一个project,第一步要做的就是登录Github,完成用户鉴权,让Github知道我是谁,然后Github才能判断我是否有权限创建一个project。

认证只关注我是谁,不管后面的业务权限如何分配。通过认证进入系统的用户,能够做什么事,则交给授权来处理。

访问(Access) VS 验证(Validation)

访问和验证可以看做是授权的两个步骤。访问解决Can I call this operation的问题,验证解决Can I access the data behind this operation的问题。对于接口来说,我能不能调用这个接口,是访问问题,它与数据无关,可以在网关层拦截。而我能够调用这个接口,但能不能操作接口后面的数据,则需要验证。再拿Github举例,假定我要删除一个project。首先,我作为登陆用户,可以访问删除project接口,但我只能删除属于我的项目,不能删除别人的项目,这就是验证要做的工作。验证一般需要在接口的业务逻辑层实现。

操作权限 VS 数据权限

操作权限 就是控制用户可以访问的操作。数据权限则控制被访问数据的可见范围。
实际上,访问 和 验证 就分别对应了 操作权限 和 数据权限。

我们一般的权限管理系统,都是针对操作权限给出的解决方案。目前比较成熟的有 Apache Shiro、Spring Security等基于RBAC模型的框架。而对于数据权限,由于跟业务结合过于紧密,目前尚无统一的成熟框架。

总结

本文介绍了权限控制相关的核心概念,并对认证和授权、访问和验证、操作权限和数据权限这几组容易混淆的概念做了澄清。希望能够帮助大家在做权限控制系统设计时少走弯路。