数据权限
示例代码:注解实现数据权限
场景
- (Get)查看某个/某多个资源时,是否能够访问?
- (List)列出所有资源时,能够访问哪些?
针对 Get 的场景,因为请求体中会携带 资源 ids,因此可以进行PreCheck。
针对 List 的场景,请求体中不包含 资源 ids
- 数据库无侵入(PostFilter):查询出所有资源,再进行过滤;
- 如果资源很多时,性能有问题;
- 对于分页查询,无法确定查询数据量,只能全查,否则过滤时的数据不准确;
- 数据库侵入(SqlWhere):查询该用户可查看的资源 ids,拼接到 SQL 语句后面;
网上的一些数据权限(Ruoyi等),通过内置几种策略来实现,不具备通用性(TODO:后续论证):
- 本人,本部门,部门及所有子部门;
- 针对分享,很难做处理;
因为资源类型有很多,如”用户“,”用户组“,”项目“和各种业务资源;
针对管理员:提供特殊权限,不需要将所有资源 ids 赋值
- AUTH_ALL,即 "*":指定任意资源 ids,都可以查询;
方案
由于对于 List 的场景,采用 SQL 侵入式的方案。如果没有请求体,则无法将用户具备的资源 ids 通过 SPEL 修改并返回(不打算采用 ThreadLocal 等方式,防止多线程的本地变量继承等问题)。
- 将 多个Get 和 List 的场景,统一成一个接口;
- 如果带资源 ids ,则是 多个Get;
- 如果不带 资源 ids(即为 null),则为 List;
针对单个Get 的场景,因为请求体中会携带 资源 id,因此可以进行PreCheck:
- 获取用户的所有资源,查看是否具备权限;
- (或)直接查询用户是否具备该资源的权限;
针对 多个Get 的场景,因为请求体中会携带 资源 id,因此可以进行PreCheck:
- 获取用户的所有资源,查看是否具备权限并过滤有权限的资源;
- (或)直接查询用户是否具备这一批资源的权限;
- 最后,将有权限的资源ids,通过 SPEL 回写参数,拼接到SQL;
针对 List 的场景,因为请求体中会携带 资源 id,因此可以进行PreCheck:
- 获取用户的所有资源,通过 SPEL 回写参数,拼接到SQL;