Winform开发框架之权限管理系统
在前一篇随笔《Winform开发框架之字典数据管理》中介绍过我Winform开发框架的总体情况,其中最重要的思路就是把常用的模块封装成控件进行重复使用,一则可以避免重复开发,提高开发效率;二则可以使用成熟的控件及技术,使得用户体验更好,更加专业。在前面介绍过的Winfrom开发框架总体思路如下所示。
在Winform框架中,其中权限管理系统、字典管理系统,都是可以做成独立的程序来使用,而且应该可以在程序中引用来查询或者获取相关的字典数据,如找某个键值的字典列表作为下拉列表,而且由于实际项目中,有的是SqlServer、有的是Access数据库的或者其他数据库,所以支持多数据库是最好的选择。
本篇主要介绍经过优化完善的权限管理系统, 其既独立又具整合性的权限管理系统,既相互独立,有相互整合,方便重用,又不需重新开发,非常方便、更提高效率。 由于权限系统精简而又能满足日常绝大多数的需要,不会复杂的难于管理,而且也是基于角色的授权访问机制(RBAC),最重要是非常适合软件的整合使用。
权限管理系统作为一个独立的模块,其主要由登陆界面、权限管理主界面(管理用户、角色、机构、功能,以及控制角色的权限等操作功能,部分界面如下所示。
给用户分配权限,首先是给相应角色授权,角色授权功能如下所示,可以编辑角色使用的功能,也可以管理该角色包含的用户,从而实现间接实现给用户分配权限的功能(这也是基于业界通用的基于角色的访问控制(RBAC)的控制法则)。
经过优化后的权限管理系统,界面及业务逻辑封装到一个类库中,我们开发的业务管理系统中集成就很简单了,主要的项目工程界面如下所示:
我编写了一个测试工程,用来模拟业务系统中调用权限管理模块的例子,界面如下所示:
相关的代码很简单,这也是利用权限管理系统后简化很多代码的根本所在:
{
// 获取所有权限管理系统的用户,并在下拉列表中展示
List < UserInfo > userList = BLLFactory < User > .Instance.GetAll();
this .txtLogin.Items.Clear();
foreach (UserInfo info in userList)
{
this .txtLogin.Items.Add(info.Name);
}
}
private void btnSecurity_Click( object sender, EventArgs e)
{
// 独立启动权限管理系统,只需一行代码即可
WHC.Security.UI.Portal.StartLogin();
}
当然,如果要判断用户的登录及角色等,可以通过下面代码来实现。
string identity = BLLFactory < User > .Instance.VerifyUser( this .txtLogin.Text, this .txtPassword.Text, Guid.NewGuid().ToString());
{
// 进一步判断用户角色
if (BLLFactory < User > .Instance.UserInRole( this .txtLogin.Text, " 管理员 " ))
{
MessageUtil.ShowTips( string .Format( " 用户【{0}】身份验证正确 " , this .txtLogin.Text));
}
else
{
MessageUtil.ShowWarning( " 该用户没有管理员权限 " );
return ;
}
}
else
{
MessageUtil.ShowWarning( " 用户名或密码错误 " );
return ;
}
权限控制的精髓就是,用户登录后,通过把用户拥有的权限获取出来,放到一个功能列表中,然后在每一个窗体中,根据用户的功能列表,显示或者屏蔽对应的功能即可,获取功能列表代码如下所示:
#region 获取用户的功能列表
Function functionBLL = new Function();
List < FunctionInfo > list = functionBLL.GetFunctionsByUser(info.ID, " WareMis " );
if (list != null && list.Count > 0 )
{
foreach (FunctionInfo functionInfo in list)
{
if ( ! Portal.gc.FunctionDict.ContainsKey(functionInfo.ControlID))
{
Portal.gc.FunctionDict.Add(functionInfo.ControlID, functionInfo);
}
}
}
#endregion
判断的时候,放在一个函数,判断用户访问的功能是否在列表中即可,代码如下所示
/// 看用户是否具有某个功能
/// </summary>
/// <param name="controlID"></param>
/// <returns></returns>
public bool HasFunction( string controlID)
{
bool result = false ;
if (FunctionDict.ContainsKey(controlID))
{
result = true ;
}
return result;
}
那么控制用户显示的界面代码如下所示:
if (Portal.gc.HasFunction( " KTV " ))
{
OutlookBarBand myBasicBand = new OutlookBarBand( " KTV包间管理 " );
myBasicBand.SmallImageList = this .imageList;
myBasicBand.LargeImageList = this .imageList;
if (Portal.gc.HasFunction( " KTV/View " ))
{
myBasicBand.Items.Add( new OutlookBarItem( " KTV包间状态视图 " , 0 ));
}
if (Portal.gc.HasFunction( " KTV/Setting " ))
{
myBasicBand.Items.Add( new OutlookBarItem( " KTV包间设置 " , 1 ));
}
if (Portal.gc.HasFunction(