基于角色的权限管理(RBAC),是一种比较流行的权限管理模型。基本思路是将权限集中到角色上,将用户与权限挂钩。更高级的权限管理可以授权到用户组以及权限的继承。RBAC的基础知识请自行参阅相关文章,此处不再赘述。最简单的RBAC框架由五张数据表构成:
1、用户表
2、角色表
3、用户角色关联表
4、权限表
5、角色权限关联表
通过五表联查即可获得一个用户的所有角色以及角色下的所有权限。
具体到UI层面,这些权限总归要以某种形式展现出来。一般是下拉菜单或者树形菜单。这里我们采用树形菜单来展示,所谓权限,在EasyUI中可以规划为一个子页面,能看到这个子页面即可在上面进行操作。有兴趣的读者可以参看我的另一篇博文easyui实现可扩展框架的几种思路 。
使用Linq to sql来查询权限数据。首先基于Easyui Tree 的格式来构造View Model。
//url属性类
public class URL
{
public string url { get; set; }
}
//节点类
public class Node
{
public string text { get; set; }
public URL attributes { get; set; }
public string iconCls { get; set; }
}
//父节点类
public class Father
{
public string text { get; set; }
public List<Node> children { get; set; }
}
Tree控件的attributes属性就是提供给用户的一个数据容器,你可以在其中放置各种自定义的数据。
将联查得到的权限数据填充到视图模型集合中并序列化成Tree控件需要的标准格式:
public string MenuTree(string userName)
{
List<Father> menu = new List<Father>();
var result = from u in m_CMContext.Users()
join ur in m_CMContext.User_Roles() on u.Name equals ur.User_Name
join r in m_CMContext.Roles() on ur.Role_Name equals r.Name
join f in m_CMContext.Role_Functions() on r.Name equals f.Role_Name
join fun in m_CMContext.Functions() on f.Fun_Name equals fun.Name
orderby r.Sequence, f.Sequence
select new { ur.Role_Name, fun.Alias,fun.IconCls, fun.URL };
var g = from c in result group c by c.Role_Name;
foreach (var i in g)
{
menu.Add(new Father());
Father tempFather = menu[menu.Count - 1];
tempFather.text = i.Key;
tempFather.children = new List<Node>();
foreach (var f in i)
{
tempFather.children.Add(new Node { text = f.Alias, iconCls = f.IconCls, attributes = new URL { url = f.URL } });
}
}
return JsonConvert.SerializeObject(menu);
}
组装Tree数据稍显繁琐。最后展现在页面中的菜单如图:
这里只为用户配置了一个审核角色,审核角色下有四个权限,这一切都是从数据库动态生成的。
角色的顺序、角色中权限的顺序以及图标和URL路径都是可以配置的。至此,基于RBAC的权限菜单树已经实现了全配置。