提醒,笔者所学习的若依为当前最新的3.8.5版本,在权限的部分做了一点优化,详情可以看作者的提交记录。这个后面会提到

优化多角色数据权限匹配规则 · 9b3767a · 若依/RuoYi-Vue - Gitee.com

这里笔者默认读者具有自定义注解,AOP,反射相关知识。

首先我们先来了解一个MySql函数find_in_set()

MySQL中的find_in_set()函数使用技巧心得与应用场景总结 - 知乎 (zhihu.com)

直接英文翻译,判断元素是否在某个集合。

注意比如这行sql的运行结果如下,详情请看上面的链接

我么来先看看演示

详细演示

比如我们给common和only角色的权限如下,并且把角色分配给若依

效果展示:只能看到自己的信息和测试部门及以下的信息

查看日志发现 执行的sql如下,注意一下我圈起来的地方

我们去查看mapper文件,发现mapper文件和我们执行的sql怎么不太一样?这个params.dataScope直接变成了一长串sql?这里就和数据权限的重点

找找这个params属性,后面发现在基类BaseEntity里面这个属性params。

知道了大概,我们开始分析这个注解吧。@DataScope

  1. 定义注解

这里注意下面作者的注释,这个在新版若依加的,旧版本不一样。

这里提到了使用权限注解@ss我们去看看类似下面这个。注意数据权限和访问权限不太一样。

这是SpringSecurity相关的权限,关于若依和SpringSecurity的分析,笔者写了好几篇,请读者自己在若依合集查看。

在@PreAuthorize("@ss.hasPermi('system:user:list')")注解中,把参数'system:user:list',传入了下面圈起来的方法。

查看该方法

这个类里面出现了RequestContextHolder,查询相关知识如下。

相关链接

面试中再问到ThreadLocal,应该这么答 - 知乎 (zhihu.com)
(150条消息) Spring Boot 源码分析——RequestContextHolder 与 ThreadLocal_Koorye的博客-CSDN博客
(150条消息) spring boot开启异步导致RequestContextHolder.currentRequestAttributes()为NULL_ERD Online的博客-CSDN博客

切面逻辑1权限相关判断

注意,这里获取了刚刚在RequestContextHolder中的@PreAuthorize("@ss.hasPermi('system:user:list')")注解的参数 'system:user:list'

在这里对权限进行了判断,这个是访问列表的权限判断(springsecurity),和访问内容的权限(@datascope)不一样哈。

切面逻辑2拼接SQL

我么们看看他的过程

首选第一个common角色进入判断4

然后第二个角色进入判断5

此时sql变为

然后将第一个or换成and

然后就进入xml文件开始拼接啦。这就变为我们最初看到的样子啦。

简单的分析一下sql拼接过程 假设有ABC三个权限,分别拼接SQL

每个权限的相关sql为A : or..a.. B: or..b.. C: or..c...

一个用户有多个角色(权限)的话就是拼接一下 or..a.. or..b.. or..c...

最后去除最前面的一个or为and 变为and(..a.. or..b.. or..c...)

最后把拼接好的sql放入param参数当中,如果用户有全部权限,那就不用拼接了。直接结束,查询全部就行

值得注意的是若依这里做了防止sql注入,处理,由于这个参数是直接拼接在mapper文件的最后,为防止恶意的sql操作,如传参加入 ;delete... 在结束上一条sql后删除一些数据之类的不好的行为

因此在sql拼接前就把变量清空。

Logo

快速构建 Web 应用程序

更多推荐