版本信息:
springboot:3.2.4
activiti:8.1.0
security:6.2.3
问题背景
整合了 security 安全框架的 springboot 项目引入 activiti 工作流,调用 activiti 接口被 security 框架的权限拦截器拦截了。
以下是两个配置一样的接口,第一个接口被拦截,而第二个接口居然能够正常访问。
原因分析
通过对比,第一个接口调用 activiti 的方法而被 security 拦截到了,但是这两个方法我都有通过 @PreAuthorize 注解设置权限,登录用户也拥有 system:test:list 权限。
最终找到原因:activiti7 开始是绑定了 security 框架,使用 activiti 的方法,需要有 ROLE_ACTIVITI_USER 或者 ROLE_ACTIVITI_ADMIN 权限,如果没有就会被 security 权限拦截器拦截,导致访问失败。
解决办法
知道原因就好解决了,既然是没有这个权限,那我们手动加入权限就好。
1、直接在 user 表中加入一个新字段 roles ,在该字段中设值 ROLE_ACTIVITI_USER
2、修改代码的 user 实体类
3、修改 UserDetailsService 代码
UserDetailsService 类是 security 框架中自定义验证的方法,类中保存用户信息、权限信息并且返回给 security 框架进行登录认证和权限管理,只需要在权限信息中加入user中的roles属性,就能手动加入 ROLE_ACTIVITI_USER 属性。
缺点分析
因为我数据库的权限表是有权限字段了,直接在用户表添加一个权限字段显得数据耦合度比较高;如果在权限表中添加数据,又得给每个用户新增一个 ROLE_ACTIVITI_USER 或 ROLE_ACTIVITI_ADMIN 记录,如果用户量多,数据量也就多起来了。
补充说明
activiti 是有绑定 security 安全框架的,即引入 activiti 依赖后就会有 security 依赖,可以直接使用安全框架。