JeecgBoot权限配置实战,搞定角色菜单和数据权限
2026/9/16 4:37:37 网站建设 项目流程

企业级系统的权限设计,往往是项目初期最容易被低估的环节。等到业务复杂起来,才发现"能登录"和"能看对数据"完全是两码事。JeecgBoot 把 RBAC 模型做进了低代码平台里,但配置得当需要理解几个关键关联。这篇结合一个真实场景,把角色菜单和数据权限的配法彻底讲透。

RBAC 在 JeecgBoot 中的实体关系

JeecgBoot 的权限体系围绕四个核心实体展开:用户角色部门菜单。理解它们的关联方式是后续配置的基础。

  • 用户:系统的最小操作单元,一个用户可以绑定多个角色
  • 角色:权限的集合载体,通过角色间接获得菜单和数据范围
  • 部门:组织架构的层级体现,同时也是数据权限的边界依据
  • 菜单:功能入口,支持细化到按钮级别的控制

这四者的关系可以概括为:用户通过角色获得菜单操作权,通过部门归属获得数据可见范围。JeecgBoot 在sys_usersys_rolesys_departsys_permission几张核心表中维护这些关联,前端渲染菜单时做交集计算,后端接口层面再做二次校验。

第一步:创建角色并分配菜单权限

假设我们要为"区域运营专员"这个角色配置权限,完整流程如下。

创建角色

进入系统管理 → 角色管理,点击新增。角色编码建议采用语义化命名,比如regional_ops,方便后续在代码中识别。角色名称填写"区域运营专员",选择状态为正常。

分配菜单权限

在角色编辑页切换到"权限配置"标签页。这里会出现完整的菜单树,勾选时需要注意两个层级:

  • 菜单级:控制左侧导航是否可见。勾选父级会自动全选子级,但建议根据实际业务逐层确认,避免过度授权。
  • 按钮级:展开具体菜单节点后,会出现"新增""编辑""删除""导出"等按钮权限。这是很多企业容易遗漏的点——只给了页面入口,没给操作按钮,用户进去只能干瞪眼。

按钮权限的开启位置:在菜单管理 → 具体菜单的"按钮权限"标签页预先定义好操作标识,比如user:adduser:edit。角色配置时这些标识会以复选框形式呈现。

数据权限的开启位置

同样在角色编辑页,找到"数据权限"下拉选项。JeecgBoot 内置了四种数据范围:

  • 全部数据
  • 本部门数据
  • 本部门及以下数据
  • 仅本人数据

这里先选择"本部门数据",下一节会详细展开部门经理的场景配置。

配置完成后,建议立即用测试账号登录验证:先看菜单是否出现,再点进去看按钮是否显示,最后尝试越权访问接口看是否被拦截。

第二步:配置部门经理的行级数据权限

实际业务中常见的需求是:部门经理只能查看本部门的数据,而普通员工只能看自己的。JeecgBoot 通过注解层面配置层面双重控制来实现。

场景设定

  • 技术部经理:能看技术部所有员工的数据
  • 技术部员工:只能看自己的数据

配置层面的控制

在角色管理中,技术部经理的角色数据权限设为"本部门及以下数据",普通员工设为"仅本人数据"。这是第一层过滤,由框架自动完成。

注解层面的控制

在需要数据权限控制的实体查询方法上,添加@PermissionData注解:

@PermissionData(pageComponent = "system/UserList") public Page<User> queryPageList(User user, Integer pageNo, Integer pageSize) { // 业务逻辑 }

pageComponent参数对应前端组件路径,框架会根据当前用户的角色数据权限,自动在 SQL 中追加WHERE条件。比如技术部经理查询时,会附加and depart_id in (技术部id, 子部门id)的过滤。

自定义数据权限规则

如果内置的四种数据范围不够用,比如需要"跨部门但限定某些产品线"的复杂规则,可以在DataPermissionRule接口的实现类中扩展。JeecgBoot 的JeecgDataPermission类提供了切入点,重写getSqlSegment方法即可注入自定义条件。

这里有个容易踩坑的点:注解生效的前提是查询必须走 MyBatis-Plus 的QueryWrapper,手写原生 SQL 或自定义 Mapper 时需要自行处理权限过滤。

第三步:扩展自定义权限规则的 Shiro 介入点

JeecgBoot 默认使用 Apache Shiro 做认证授权。如果需要扩展自定义权限规则,比如基于项目维度、客户维度的细粒度控制,需要在 Shiro 配置中介入。

自定义 Realm

继承AuthorizingRealm,重写doGetAuthorizationInfo方法:

@Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 获取当前用户 LoginUser user = (LoginUser) principals.getPrimaryPrincipal(); // 加载角色 Set<String> roles = userService.getUserRoles(user.getId()); info.setRoles(roles); // 加载权限(含自定义规则) Set<String> permissions = permissionService.getUserPermissions(user.getId()); info.setStringPermissions(permissions); return info; }

配置 Shiro 过滤器链

ShiroConfig中,将自定义 Realm 注册到SecurityManager

@Bean public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); manager.setRealm(customRealm()); // 其他配置... return manager; }

自定义权限注解

对于无法通过角色或菜单表达的业务规则,可以定义自定义注解,配合 AOP 切面在方法执行前做权限校验。比如@ProjectPermission(projectId = "#projectId"),通过 SpEL 表达式解析参数,再查询当前用户是否有该项目的操作权。

两种开发方式的维护成本对比

权限需求在项目生命周期中频繁变动是常态。对比纯代码开发与平台配置两种方式:

维度纯代码开发JeecgBoot 平台配置
新增角色改代码、发版、重启界面点选,即时生效
调整菜单权限修改注解或配置文件角色管理界面勾选
数据规则变更重写 SQL 片段或切面逻辑修改角色数据权限选项
审计追溯需自行实现操作日志内置权限变更记录

显然,对于频繁调整的权限需求,平台配置的效率优势明显。但也要注意边界:当权限规则复杂到需要大量自定义代码时,维护成本会陡增。建议把常见模式(部门隔离、个人隔离)交给平台,特殊规则通过扩展点实现,保持两者的平衡。

多租户场景的额外注意项

如果系统采用 SaaS 多租户架构,权限隔离需要额外关注两点:

租户间的数据隔离

JeecgBoot 的多租户实现中,sys_tenant表与核心权限表存在关联。配置角色时,确保tenant_id字段正确赋值,避免租户 A 的角色被租户 B 的用户误用。框架在查询时会自动追加租户条件,但初始化数据时需要校验。

超级管理员与普通租户的权限差异

平台超级管理员能跨租户操作,这个角色的数据权限建议设为"全部数据",但在具体业务实现中,跨租户查询需要显式指定租户 ID,不能依赖框架的自动注入。否则可能出现超级管理员查看数据时,因缺少租户过滤而返回全量数据的性能问题。

权限配置没有一劳永逸的方案,但理解框架的设计意图后,可以少走很多弯路。建议每次调整权限后,用不同角色的测试账号完整走一遍业务流程,特别是边界场景——比如部门经理离职交接、员工跨部门调岗时的数据可见性变化。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询