1.RBAC模型
一.什么是RBAC
- 权限系统提的最多的就是 RBAC(Role-Based Access Control 基于角色的访问控制)。 所谓角色,其实就是权限的集合,某个角色就是某几个权限的结合。其目的是为了简化授权和鉴权的过程。
二.表结构分析
- 企业开发中 RBAC模型设计为7张表,其中4张为基础表,3张为中间表。
- 用户与角色
用户和角色为多对多关系,通过用户角色中间表关联
tb_admin 管理员表:
tb_role 角色表:
tb_admin_role 管理员角色中间表: - 角色与权限
角色和权限为多对多关系,通过角色权限中间表关联
tb_role 角色表:
tb_resource 权限表(资源表):
tb_role_resource 角色资源中间表: - 权限与菜单
权限和菜单为多对多关系,通过权限菜单中间表关联
tb_resource 权限表(资源表):
tb_menu 菜单表:
tb_resource_menu 资源菜单中间表:
2.管理员角色设置
一.需求分析
- 管理员和角色为多对多关系,在保存管理员时实现对管理员角色中间表的添加。
二.思路分析
- 提交角色设置
- 创建管理员角色中间表的实体类和数据访问接口
- 创建组合实体类,包含管理员实体类和角色ID集合两个属性
- 修改管理员实体类,为id添加以下注解可以标识该主键为自增
- 修改管理员add方法,取出管理员实体保存,取出角色ID集合,循环添加到管理员角色中间表。
- 注意在保存管理员密码时需要对密码进行bcrypt加密。
- “所属角色”使用elementui的select选择器 ,为 el‐select 设置 multiple 属性即可启用多选
- 读取角色设置
- 修改findById方法的返回值为组合实体类,修改其中的逻辑,组合实体类的角色id集合需要查询管理员角色中间表。
- 修改update方法,删除原来的相关的中间表数据,再循环添加中间表数据。
- 读取后需要把密码属性设置为null, 如果用户没有在界面输入密码则保持密码不变,如果填写了密码需要进行bcrypt加密。
3.角色权限设置
一.需求分析
- 显示所有的权限列表,并自动勾选已经保存的权限。用户勾选权限后,点击提交,将勾选的权限id提交给后端保存
二.思路分析
- 提交权限设置
- 创建角色权限中间表的实体类和数据访问接口
- 前后端约定要提交的数据格式,包括“角色id”和“权限id列表”。根据约定的数据格式创建组合实体类。
- 后端添加方法,接收组合实体类参数,提取“角色id”和“权限id列表”,循环读取权限id插入到角色权限中间表中。
- 读取权限设置
- 后端查询权限表(资源表),以树状结构返回数据。前端使用两层v-for循环输出列表。
- 后端添加方法,根据角色查询权限id列表,前端获取权限id列表后实现复选框的勾选。
4.用户权限设置
一.需求分析
- 当用户执行一个不存在的权限的url,需要拦截请求。
二.spring security授权控制
- 基于URL访问控制
在UserDetailsServiceImpl的loadUserByUsername方法,实现对当前用户的授权
修改applicationContext_security.xml
hasAnyAuthority():拥有任意权限都可以访问
hasAuthority('brand'): 拥有brand的权限可以访问
hasAnyAuthority('goods_add','goods_edit')" :拥有goods_add和goods_edit其中一个权限就可以访问 - 基于方法的访问控制
对当前用户授权,同上 ,对方法的访问控制如下:- 修改applicationContext_security.xml ,增加配置 ,启用注解
- 在进行权限控制的方法上添加注解
- 修改applicationContext_security.xml ,增加配置 ,启用注解
三.思路分析
- 编写SQL语句,通过登录名查询资源KEY列表
- 数据访问接口新增方法,根据登录名查询资源KEY列表
- 服务层实现根据登录名查询资源KEY列表
- UserDetailsServiceImpl的loadUserByUsername方法,调用根据登录名查询资源KEY列表的方法,将资源key列表添加到当
前用户。 - )修改applicationContext_security.xml,添加对url的拦截,或在方法上添加注解实现对方法的拦截。
5.用户菜单筛选
一.需求分析
- 用户登录后进入主界面,显示的菜单为用户所拥有的权限关联的菜单。不具有权限的菜单不显示。
二.思路分析
- 编写SQL语句,根据当前登录名获取菜单列表的方法
注意通过上述语句,获取的菜单列表只包含三级菜单,而我们需要返回包括一级菜单、二级菜单和三级菜单的菜单列表。只要三级菜单存在,就要有它的二级菜单;只要有一个二级菜单就要有它的一级菜单。 - 查询二级菜单列表:
- 查询一级菜单列表:
- 最后我们通过UNION运算符将三个语句连接成一条语句
- 将上述SQL封装为查询方法
- 在controller获取当前用户名,调用上述查询方法。