基于asp.net2.0中membership系统角色、用户、资源的权限设计
经常做系统,系统中都要求有用户、角色的权限分配,所以今日对其进行总结下自己的观点。
首先我的用户管理系统都是基于微软的membership的,所以首先要将其安装配置到系统中,安装方法请看这里《如何配置安装membership》,这里就不再赘述了。
我的结构是这样的:
表:
membership已经为我们提供了用户表与权限表(aspnet_Roles、aspnet_Membership、aspnet_Users),还有其它一些辅助作用的表。我的membership基于这些表,那么每个系统的用户属性肯定不会一样,所以需要建立自己的“用户信息表”,用户信息表要与aspnet_Membership表相关联,这样就解决了系统中的用户信息多变化的情况。membership中的aspnet_UsersInRoles表已经将用户与角色相关联了,不必我们再操心了。
大致思想:
为了实现后期灵活对用户的权限进行在线实时配置,所以用户不直接面对资源(资源可以简单的理解为系统中的一个网页),由角色来直接面对资源(角色与资源之间的映射通过xml文件来配置),用户与角色之间membership已经给我们提供了很多强大的方法来支持了,所以整个成员资格管理系统就变得简单了,后期也很好的维护了。
大多系统后台框架是上中下结构,中间又分为左右框架,左边一般是系统的管理链接,我用的是PanelBar控件结合xml文件《查看.net系统中如何使用PanelBar控件》,程序根据当前登陆用户的角色动态加载xml文件中的内容,这样就非常轻松的实现了资源根据角色的动态绑定。
效果图:
PanelBar效果
角色管理图
角色下用户的配置图
部分代码:
PanelBar所调用的xml文件部分代码:
注: UserDataString属性对应的就是角色的名称
每一项(含组、细节)均有一个UserDataString属性,UserDataString与membership中的角色对应
如果组中的UserDataString属性为空,则意味这个组为公共角色组,都可以进入
如果细节中的UserDataString属性为空,则意味只要能进入这个组中的角色用户都可以管理它
根据组中的UserDataString和细节中的UserDataString可以灵活配置权限
<Group Caption="用户基本信息管理" UserDataString="用户基本信息管理">
<Item Caption="基础数据维护" IconImage="/item.gif" Target="main" URL="#" UserDataString="" />
<Item Caption="密码修改" IconImage="/item.gif" Target="main" URL="#" UserDataString="" />
</Group>
<Group Caption="系统基础数据管理" UserDataString="系统基础数据管理">
<Item Caption="省市县数据管理" IconImage="/item.gif" Target="main" URL="#" UserDataString="" />
<Item Caption="项目类型数据管理" IconImage="/item.gif" Target="main" URL="#" UserDataString="" />
<Item Caption="公司部门数据管理" IconImage="/item.gif" Target="main" URL="#" UserDataString="" />
</Group>
<Group Caption="公告管理" UserDataString="公告管理">
<Item Caption="发布公告" IconImage="/item.gif" Target="main" URL="#" UserDataString="" />
<Item Caption="管理公告" IconImage="/item.gif" Target="main" URL="#" UserDataString="" />
</Group>
<Group Caption="系统管理" UserDataString="系统管理">
<Item Caption="角色管理" IconImage="/item.gif" Target="main" URL="membership/role_add.aspx" UserDataString="" />
<Item Caption="数据库备份" IconImage="/item.gif" Target="main" URL="backdata.aspx" UserDataString="" />
</Group>
用户登陆后对xml文件进行动态加载,只选择属于当前用户角色的资源项:
/// <summary>
/// 由当前用户的登录角色进行定位
/// </summary>
/// <param name="roles">角色列表</param>
private void bindGUdata(string[] roles)
{
if (roles.Length > 0)//当前登陆用户有角色
{
string tmpudata = "";
object mytpmo;
for (int i = 0; i < this.PanelBar1.Groups.Count; i++)
{
mytpmo=this.PanelBar1.Groups[i].UserData;
if (mytpmo != null)
{
tmpudata = mytpmo.ToString().Trim();
}
else
{
tmpudata = "";
}
if (tmpudata!="")//看是否属于公共模块
{
if (!Common.commonother.checkArray(roles, tmpudata))//看用户是否有此组权限
{
this.PanelBar1.Groups.Remove(i);//没有则移除
i = -1;
}
else//如果有组的权限看细节的权限
{
this.commonitems(this.PanelBar1.Groups[i].Items, roles);
}
}
else//属于公共模块则检查它的细节
{
this.commonitems(this.PanelBar1.Groups[i].Items, roles);
}
}
}
else//没有任何角色则全部清空
{
this.PanelBar1.Groups.Clear();
}
}
/// <summary>
/// 细节权限控制
/// </summary>
/// <param name="itemss">所在权限组的序列</param>
/// <param name="roles">所检查的用户的权限</param>
private void commonitems(Coalesys.PanelBar.Items itemss, string[] roles)
{
string tmpudata2 = "";
object tmpo;
for (int j = 0; j < itemss.Count; j++)
{
tmpo=itemss[j].UserData;
if (tmpo != null)
{
tmpudata2 = tmpo.ToString().Trim();
}
else
{
tmpudata2 = "";
}
if (tmpudata2 != "")//有细节权限控制
{
if (!Common.commonother.checkArray(roles, tmpudata2))//看用户是否有此细节权限
{
itemss.Remove(j);//没有则移除
j = -1;
}
}
}
}
在用户登陆后台时进行判断加载:
if (!this.IsPostBack)
{
bindPannelBar();//加载PannelBar控件,说见《Coalesys PanelBar for ASP.NET 控件的使用》
bindGUdata(Roles.GetRolesForUser());//调用上面我写的函数。
}
OK,上述的membership构架介绍完毕,基本是个通用的,您做任何一个有成员管理系统的都可以用到,而且后期管理维护也非常方便。
文章来源(WEB开发技术知识库):http://cn-web.com/cnweb/0/464/article/