版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Hemk340200600/article/details/78149277
基于角色的权限访问控制(Role-BasedAccess Control)。在RBAC中,权限与角色相关联,通过使用户成为适当的角色而得到这些角色的权限。用户可以很容易地从一个角色被指派到另一个角色。角色可依新的需求和系统的合并而赋予新的权限,而权限也可根据需要而从某角色中回收。这就极大地简化了权限的管理。
资源树将整个系统的功能按模块划分,如用户管理模块,文件管理模块,用户管理模块下又有管理员管理,工作单位管理,系统用户管理等。而每一个资源模块下面,都可能有多个权限需要控制,比如工作单位管理,至少要有最基本的查看,修改,增加,删除四个功能,为了让特定的角色拥有特定的功能,我们需要对功能设置权限,因此工作单位管理模块至少需要有以下权限:查看工作单位,修改工作单位,删除工作单位,添加工作单位。因此资源与权限的关系为:一个资源拥有多个权限。为了在后台方便编程人员控制权限,每个权限都会有一个权限编码。通常相同资源下用相同的前缀来表示,比如上面那个可以用work:list,work:add,work:delete,work:edit
资源树构建过程:
先获取当前用户的所有角色,从而得到用户的所有权限。根据权限获得资源resourceId列表,通过resourceId将用户拥有的资源树利用组合模式组合起来,传给前端,由前端进行解析生成视图。
后端代码如下:
/**
* 生成用户的资源权限的树结构
* @return
* @throws Exception
*/
public List<Resource> getUserPermTree(User currentUser)throws Exception{
log.info("===生成用户的资源权限的树结构===");
List<Resource> result = new ArrayList<>();
//权限数据预处理
Map<Long, List<Permission>>permMap = new HashMap<>(50);
List<Role> roles=userMapper.getRoles(currentUser.getId());//获取用户所有角色
List<Permission> perms=new ArrayList<>();//获取用户所有权限
for(Role role:roles){
List<Permission> temp=permissionMapper.listByRole(role.getId());
perms.addAll(temp);
}
perms.forEach(p -> {
if(!permMap.containsKey(p.getResid()))
permMap.put(p.getResid(), newArrayList<>());
permMap.get(p.getResid()).add(p);
});
//资源数据处理
Map<Long, Resource> resourceMap= new TreeMap<>();
Set<Long> rids=new HashSet<>();
for(Permission permission:perms){//根据权限获取资源id列表
rids.add(permission.getResid());
}
CopyOnWriteArrayList<Resource>resources=resourceMapper.listByids(rids);
for(Resource resource:resources){
getFRes(resource,resources);//寻找资源的父节点(菜单头)
}
resources.forEach(r -> {
//将权限与资源关联起来
if(permMap.containsKey(r.getId())){
r.setPerms(permMap.get(r.getId()));
}
//清除缓存带来的影响
r.getSub().clear();
resourceMap.put(r.getId(), r);
if(r.getPid() == null ||r.getPid() == 1){
result.add(r);
}
});
//再一次循环构建资源的父子关系
resources.forEach(r -> {
if(r.getPid() != null && resourceMap.containsKey(r.getPid())){
Resource resource = resourceMap.get(r.getPid());
resource.getSub().add(r);
}
});
return result;
}
private void getFRes(Resource resource,List<Resource>resources){
if(resource.getPid()!=null||resource.getPid()!=1){
Resource father=resourceMapper.selectByPrimaryKey(resource.getPid());
if(father!=null&&!father.getName().equals("root")){
if(!resources.contains(father)){
resources.add(father);
}
getFRes(father,resources);
}else{
return;
}
}else{
return;
}
}
前端jsp代码:
<c:forEach items="${menuList}"var="menu">
<div title="${menu.name}"data-options="iconCls:'icon-application-cascade'" style="padding:5px;" >
<ul class="ui-side-tree">
<c:forEach items="${menu.sub}"var="subMenu">
<c:if test="${subMenu.sub.size()eq 0}">
<li><a href="${ctx}${subMenu.url}">${subMenu.name}</a></li>
</c:if>
<c:if test="${subMenu.sub.size()ne 0}">
<li>
<span>${subMenu.name}</span>
<ul>
<c:forEachitems="${subMenu.sub}" var="sub">
<li><ahref="${ctx}${sub.url}">${sub.name}</a></li>
</c:forEach>
</ul>
</li>
</c:if>
</c:forEach>
</ul>
</div>
</c:forEach>