title: Shrio底层RBAC基本思想
date: 2018-04-05 8:30:01
tags:
- [crm]
categories: - [java]
- [project1]
- [crm]
权限管理
RBAC是基于角色的访问控制(Role-Based Access Control
)在RBAC中,权限与角色相关联,用户通过扮演适当的角色从而得到这些角色的权限。这样管理都是层级相互依赖的,权限赋予给角色,角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
所谓rbac权限系统,就是不同的用户在一个系统中扮演不同的角色,而不同的角色又可以操作不同的模块(相当于拥有不同的功能)。
其中用户角色的授权认证是最为出彩的部分。
表设计
需要五张表:
- 用户表-》t_user
- 用户角色表-》t_user_role-》中间表
- 角色表-》t_role
- 权限表-》t_permission-》中间表
- 资源表-》t_module
表结构如下:
实体对应关系
可以分为三大实体。
模块划分
从表结构设计可以看出:这里有三张主表(t_user,t_role,t_module),功能实现上这里划分为三大模块:
用户管理
-
用户基本信息维护(t_user)
-
角色分配(t_user_role)
角色管理
- 角色基本信息维护(t_role)
- 角色授权与认证(t_permission)
资源管理
- 资源菜单信息维护(t_module)
功能分析
用户模块管理
用户表(t_user)数据基本维护
用户表的增删改查
用户角色分配
给用户分配响应的角色,角色拥有对应的权限,不同的权限可以操作系统中不同的模块和功能。
使用layui的formSelects给用户分配角色。
角色模块管理
角色表(t_role)数据基本维护
角色并不是写死的,而是可以自行增删改查。
角色授权(t_permission)
给指定角色分配能够操作那些菜单的权限,对权限表处理。
前端使用zTree,对角色进行授权。
zTree主要使用后端的json数据,为了给前台传递这样的树形数据,需要在后端顶一个TreeDto对象。
授权实现
角色如果存在原始权限记录先执行删除(根据角色id 删除) 后续添加新的权限记录(批量添加操作)。
权限认证
系统对用户权限进行认证。有驾照要亮出来,不是你说有就有。
前台实现上使用freemarker和内建函数。
后台主要是连表查询出t_permission表中的acl_value字段(权限码)。
数据库中的t_permission:
连表查询语句:
<select id="queryUserHasRolesHasPermissions" parameterType="int" resultType="java.lang.String">
select distinct p.acl_value
from t_user_role ur left join t_permission p on ur.role_id = p.role_id
where ur.user_id=#{userId}
</select>
将查询到的acl_value放入到session中传递给前台:
/**
* 后端管理主页面
* @return
*/
@RequestMapping("main")
public String main(HttpServletRequest request){
Integer userId = LoginUserUtil.releaseUserIdFromCookie(request);
request.setAttribute("user",userService.selectByPrimaryKey(userId));
List<String> permissions=permissionService.queryUserHasRolesHasPermissions(userId);
request.getSession().setAttribute("permissions",permissions);
return "main";
}
通过前台的if标签以及内建函数来在主页中判断某个用户是否含有该模块的权限码,如下:
<#if permissions?seq_contains("10")>
<li class="layui-nav-item">
<a href="javascript:;" class="layui-menu-tips"><i class="fa fa-street-view"></i><span class="layui-left-nav"> 营销管理</span> <span class="layui-nav-more"></span></a>
<dl class="layui-nav-child">
<#if permissions?seq_contains("1010")>
<dd>
<a href="javascript:;" class="layui-menu-tips" data-type="tabAdd" data-tab-mpi="m-p-i-1" data-tab="sale_chance/index" target="_self"><i class="fa fa-tty"></i><span class="layui-left-nav"> 营销机会管理</span></a>
</dd>
</#if>
<#if permissions?seq_contains("1020")>
<dd>
<a href="javascript:;" class="layui-menu-tips" data-type="tabAdd" data-tab-mpi="m-p-i-2" data-tab="cus_dev_plan/index" target="_self"><i class="fa fa-ellipsis-h"></i><span class="layui-left-nav"> 客户开发计划</span></a>
</dd>
</#if>
</dl>
</li>
</#if>
菜单模块管理
自关联表(父子关联表)
如果parent_id=-1,表明已是最上级菜单
菜单模块(t_module)数据维护
主要是上下级菜单维护。
共有三级菜单。
菜单层级
3层。
每一层菜单名不可重复。
每一个菜单项权限码全局唯一。
二级菜单url必须配置,一级三级不用考虑
菜单添加
菜单删除
菜单在执行删除时,级联删除权限表对应的权限记录(根据菜单id执行删除)