【基于角色的访问控制RBAC】权限与资源树

版权声明:本文为博主原创文章,未经博主允许不得转载。 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>


猜你喜欢

转载自blog.csdn.net/Hemk340200600/article/details/78149277