跳转至

数据权限

示例代码:注解实现数据权限

场景

  • (Get)查看某个/某多个资源时,是否能够访问?
  • (List)列出所有资源时,能够访问哪些?

针对 Get 的场景,因为请求体中会携带 资源 ids,因此可以进行PreCheck

针对 List 的场景,请求体中不包含 资源 ids

  • 数据库无侵入(PostFilter:查询出所有资源,再进行过滤;
  • 如果资源很多时,性能有问题;
  • 对于分页查询,无法确定查询数据量,只能全查,否则过滤时的数据不准确;
  • 数据库侵入(SqlWhere):查询该用户可查看的资源 ids,拼接到 SQL 语句后面;

网上的一些数据权限(Ruoyi等),通过内置几种策略来实现,不具备通用性(TODO:后续论证):

  • 本人,本部门,部门及所有子部门;
  • 针对分享,很难做处理;

因为资源类型有很多,如”用户“,”用户组“,”项目“和各种业务资源

针对管理员:提供特殊权限,不需要将所有资源 ids 赋值

  • AUTH_ALL,即 "*":指定任意资源 ids,都可以查询;

方案

由于对于 List 的场景,采用 SQL 侵入式的方案。如果没有请求体,则无法将用户具备的资源 ids 通过 SPEL 修改并返回(不打算采用 ThreadLocal 等方式,防止多线程的本地变量继承等问题)。

  • 将 多个GetList 的场景,统一成一个接口;
  • 如果带资源 ids ,则是 多个Get
  • 如果不带 资源 ids(即为 null),则为 List

针对单个Get 的场景,因为请求体中会携带 资源 id,因此可以进行PreCheck

  • 获取用户的所有资源,查看是否具备权限;
  • (或)直接查询用户是否具备该资源的权限;

针对 多个Get 的场景,因为请求体中会携带 资源 id,因此可以进行PreCheck

  • 获取用户的所有资源,查看是否具备权限并过滤有权限的资源;
  • (或)直接查询用户是否具备这一批资源的权限;
  • 最后,将有权限的资源ids,通过 SPEL 回写参数,拼接到SQL;

针对 List 的场景,因为请求体中会携带 资源 id,因此可以进行PreCheck

  • 获取用户的所有资源,通过 SPEL 回写参数,拼接到SQL;