权限管理工具的使用
在当今商业软件的开发中有一项功能是必不可少的,这就是权限工具,想必大家对权限这个词不会太陌生,应为在我们身边的很多软件上都用到了权限,比如说最常见的Windows操作系统,就使用到了权限,但是在实际的开发过程中,权限是个相当麻烦的东西。大家都在寻找一种简易的权限管理方式,这个时候我们发现了CG.Security这个组件,这是一个非常优秀的功能权限管理组件,它可以让我们非常简便的来控制软件的权限。
使用CG.Security你可以任意添加删除权限、角色和权限。可以通过大多数的权限管理方式给用户赋予角色或直接给用户赋予权限。
好了,简短介绍了CG.Security的功能后下面将为大家来讲解下该组件的用法。在讲解之前请首先到http://www.codeproject.com/csharp/CGSecurity.asp上下载该组件。
下面的讲解会分两个部分:
第一部分将讲解该类库中常见的一些方法属性的用法。第二部分通过一个小DEMO,给大家一个感性的认识,让大家了解在实际开发中如何使用CG.Security。
一、 类库的常用方法
在这个组件中用了六个类来分别实现了用户管理、权限管理和角色管理。
UserManager(用户管理类):该类提供了添加、删除和查找用户的方法。
RoleManager(角色管理类):该类提供了添加、删除和查找角色的方法。
RightManager(权限管理类):该类提供了添加、删除和修改权限的方法。
UserRightManager(用户权限管理类):该类的作用是使用户和权限关联,也提供了增、删、查的功能,使用此类,可以为某个用户直接赋予权限。
UserRoleManager(用户角色管理类):该类和上面的UserRightManager相似,也提供了相似的功能,所不同的是该类是把用户和角色进行关联。
RoleRightManager(角色权限管理类)该类提供了角色和权限关联的功能。
在介绍了上述六个类后,下面还要为大家介绍在实际开发中会用到的一个类。
SecurityManager.cs 类,该类提供了登陆验证(Authenticate)和获得该用户权限列表(EffectiveRights)的功能。使用该类我们可以判断用户的合法性并且能得到当前用户的权限列表。
上面介绍了权限管理组件中几个常见类的功能。让大家对权限管理组件有一个全面的了解,下面的一部分我将一步一步做出一个小DEMO让大家对这个组件有一个感性的认识。OK,偶们进入下一环节吧。
二、 做一个小Demo来演示如何使用这个权限工具
一、 做一个小Demo来演示如何使用这个权限工具
1. 我们在这个Demo中会实现数据权限和功能权限两种权限管理功能。首先我们要从网上下载该组件,该组件可以从http://www.codeproject.com/csharp/CGSecurity.asp上找到,在下载后在bin/release目录下找到CG.Security.dll文件。
2.新建一个解决方案CG.SecurityTest。
3.然后在Form1上添加一个mainMenu,然后在上面添家4个子项,把他们分别命名为mlTest1, mlTest2, mlTest3, mlTest4,然后把他们的Visible设置为false。
4.当添加完菜单后我们还要添加一个dataGrid 和3个按钮。
把dataGrid的name改为dgView;3个按钮分别命名为btnAllUser、btnTest1和btnView
然后把btnTest1的Enabled属性设置为false。
5.上面添加的是我们的主界面,下面我们还要添加一个用来输入用户名密码等信息的辅助界面,在工程上添加一个新的Windows窗体,然后命名为FormValue。当窗体新建好后在窗体上新建textbox、button一样两个。textbox分别命名为txtName,txtPwd,button分别命名为btnOK,btnCancel。并且把btnOK的dialogresult属性设置为OK,btnCancel的dialogresult属性设置为Cancel。窗体设置完后我们在代码中添加两个属性
public string UID
{
get{return txtName.Text.Trim();}
}
public string PWD
{
get{return txtPWD.Text.Trim();}
}
Ok经过上述三个步骤之后我们的界面工作就完成了,下面我们将开始实现他们的具体功能.。
6.首先在项目种引用CG.Security.dll这个组件。在FORM1上导入CG.Security和CG.Security.Principal这两个命名空间。
using CG.Security;
using CG.Security.Principal;
:)这一步是必不可少的。
7. 在添加完引用后。我们还有一个东西要准备-配置文件,那么首先我们添加一个新的App.Config,然后Copy下列代码到App.Config中:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="CG.Security.Data">
<section name="runtimeSetup" type="CG.Security.Data.Configuration.DataSettingsHandler, CG.Security" />
</sectionGroup>
</configSections>
<CG.Security.Data>
<runtimeSetup defaultSection="Access">
<installedAssembly>
<add
sectionName="Access"
targetAssembly="CG.Security"
targetNamespace="CG.Security.Data.Access"
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F:/tempfile/CGSecurityDemo/bin/Debug/security.mdb"
/>
</installedAssembly>
</runtimeSetup>
</CG.Security.Data>
</configuration>
上述的配置文件大家可以看到是连接数据库的一些信息,他使用到了CG.Security.Data.Configuration.DataSettingsHandler这个类来读取数据库信息,在配置文件中我们可以很清楚的看到连接字符串,该配置文件使用Oledb连接到指定目录下的Access数据库。应为我是放在F盘的,这里大家要根据自己数据库存放的实际位置来。当一切配置都完成了的时候,我们就开始实现具体的代码了。
8.进入应用程序第一步肯定就是要验证当前用户的合法性啦,ok 那么我们首先从窗体的加载事件开始讲起:
首先我们要在定义一个全局的string数组 str。
然后在FormLoad事件中添加如下的代码。
//实例化登陆窗体
FormValue fv = new FormValue();
if(fv.ShowDialog(this)!=DialogResult.OK)
{
this.Close();
return;
}
//验证用户的ID和Password
if(!SecurityManager.Authenticate(fv.UID,fv.PWD))
{
MessageBox.Show("用户名或密码不正确!");
this.Close();
return;
}
System.AppDomain.CurrentDomain.SetThreadPrincipal(
new CustomPrincipal(new CustomIdentity(fv.UID))
);
OleDbDataReader dataread = (OleDbDataReader)UserManager.FindByUserName(fv.UID);
dataread.Read();
str = SecurityManager.EffectiveRights(dataread.GetInt32(0));
//循环每个权限
foreach(string strSingle in str)
{
switch(strSingle)
{
case "Test 1":
miTest1.Visible = true;
btnTest1.Enabled = true;
break;
case "Test 2":
miTest2.Visible = true;
break;
case "Test 3":
miTest3.Visible = true;
break;
case "Test 4":
miTest4.Visible = true;
break;
}
}
大家看到上述代码就是一个权限管理的典型应用,我将为大家一步一步讲解这段代码。
首先我们可以看到这样一段代码
FormValue fv = new FormValue();
if(fv.ShowDialog(this)!=DialogResult.OK)
{
this.Close();
return;
}
该代码是首先实例化一个输入用户名密码的窗体,然后判断用户是否点击了OK,如果用户没有点击OK则退出程序。
if(!SecurityManager.Authenticate(fv.UID,fv.PWD))
{
MessageBox.Show("用户名或密码不正确!");
this.Close();
return;
}
这段代码就是精华之所在了,SecurityManager类是一个验证类,在这里我们调用了它的Authenticate方法,该方法接受两个参数,用户名和密码。并返回一个BOOL值,借此我们可以判断该用户的用户名密码是否正确。
System.AppDomain.CurrentDomain.SetThreadPrincipal(
new CustomPrincipal(new CustomIdentity(fv.UID))
);
该句的意思是把某一用户绑定到线程的主对象上,在这里我们把当前登陆的用户ID传进去,那么在整个程序中都可以知道当前登陆的用户。
OleDbDataReader dataread = (OleDbDataReader)UserManager.FindByUserName(fv.UID);
dataread.Read();
str = SecurityManager.EffectiveRights(dataread.GetInt32(0));
上面一段代码就是讲如何使用权限了。首先我们调用UserManager.FindByUserName方法得到一个DataReader对象(该方法是通过用户名来查找用户的信息),然后读取DataReader对象取得当前用户的ID。
最后调用SecurityManager.EffectiveRights方法列出该用户拥有的所有权限保存在一个字符串数组里面。
//循环每个权限
foreach(string strSingle in str)
{
switch(strSingle)
{
case "Test 1":
miTest1.Visible = true;
btnTest1.Enabled = true;
break;
case "Test 2":
miTest2.Visible = true;
break;
case "Test 3":
miTest3.Visible = true;
break;
case "Test 4":
miTest4.Visible = true;
break;
}
}
在这里我们刚才得到的权限数组,然后在判断当该用户是否拥有某个功能权限,例如Test 1权限的时候就让他使用Test1菜单和btnTest1按钮等。
这个时候大家可以编译程序,拿admin用户进系统和拿user进系统有什么不同之处呢?呵呵,大家可以看大使用User进去的时候菜单Test1和Test4不见了,还有就是btnTest1按钮变成灰色的了。
9. 上面,我们讲述了怎么使用功能权限,接下来,我将利用一个主从表的示例程序来为大家讲解如何使用数据权限,我们最后要实现的效果是拥有Test4权限的用户可以即看到主表又看到从表,反之则只能看到主表。
好了,首先我们在bin/debug目录下添加一个orders.mdb数据库,然后在里面分别建2张表orders和orderlist。
Orders表字段如下
ordered 自动编号
orderType 文本 (订单类别)
orderTimer 日期时间 (发生时间)
orderlist表字段如下
orderListID 自动编号
orderid 数字 (主表的ID)
ProdName 文本 (商品名称)
Count 数字 (数量)
当大家把上面的表格式建立好了以后把orders和orderlist表的orderid值进行关联。
上述步骤做完了后就往数据库里面添加几条数据。
OK数据库准备好了,我们也该看看怎么来实现了,在btnView的click事件中添加如下的代码:
OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=orders.mdb");
con.Open();
OleDbDataAdapter da = new OleDbDataAdapter("select * from orders",con);
DataSet ds = new DataSet();
da.Fill(ds," Main ");
dgView.DataSource = ds.Tables[0];
dgView.TableStyles.Clear();
DataGridTableStyle dts = new DataGridTableStyle();
DataGridTextBoxColumn dcstype = new DataGridTextBoxColumn();
DataGridTextBoxColumn dcsName = new DataGridTextBoxColumn();
dcstype.MappingName = "orderType";
dcstype.HeaderText = "类型";
dcsName.MappingName = "orderTimer";
dcsName.HeaderText = "时间";
dts.GridColumnStyles.Add(dcstype);
dts.GridColumnStyles.Add(dcsName);
dts.MappingName = ds.Tables[0].TableName;
dgView.TableStyles.Add(dts);
foreach(string stra in str)
{
//如果当用户拥有该权限的时候可以看到从表里面的内容
if(stra=="Test 4")
{
OleDbDataAdapter daList = new OleDbDataAdapter("select * from orderList where orderid in(select orderid from orders)",con);
daList.Fill(ds,"List");
ds.Relations.Add(ds.Tables[0].Columns["orderid"],ds.Tables[1].Columns["orderid"]);
DataGridTableStyle dtL = new DataGridTableStyle();
DataGridTextBoxColumn dclName = new DataGridTextBoxColumn();
DataGridTextBoxColumn dclCount = new DataGridTextBoxColumn();
dclName.MappingName = "prodName";
dclName.HeaderText = "商品名";
dclCount.MappingName = "count";
dclCount.HeaderText = "数量";
dtL.GridColumnStyles.Add(dclName);
dtL.GridColumnStyles.Add(dclCount);
dtL.MappingName = ds.Tables[1].TableName;
dgView.TableStyles.Add(dtL);
break;
}
}
上面的代码很简单,都是常用的数据库操作,我要讲解的是便利循环的地方。
foreach(string stra in str)
{
//如果当用户拥有该权限的时候可以看到从表里面的内容
if(stra=="Test 4")
{
OleDbDataAdapter daList = new OleDbDataAdapter("select * from orderList where orderid in(select orderid from orders)",con);
daList.Fill(ds,"List");
ds.Relations.Add(ds.Tables[0].Columns["orderid"],ds.Tables[1].Columns["orderid"]);
……
}
上面这段代码也是来遍历当前用户拥有的权限。然后判断是否拥有Test 4权限,如果拥有Test4权限的话就查询出从表的记录然后和主表关联,如果没有Test 4权限的话就不查询出从表。
最后1分钟:
经过上面的步骤一个权限管理Demo就完成了,你可以使用Admin和user两个用户登陆看看,你可以很清楚的看到Admin可以操作所有的菜单和查看主从表的数据,但是user用户只能操作test2和test3菜单,并且只能看到主表的数据。
回顾上面的文档,我首先为大家介绍了该组件的常用类和常用方法,在第二部分我们通过一个实例来实现如何在程序中使用功能权限和数据权限。这样一个完整的权限管理Demo就完成了,当然了大家也可以根据自己的需要来增加或删除一些不需要的功能,在本文中一直没有提及到该组件自带的Demo,应为它自带的Demo是作为授权工具用的,并且操作起来十分简单,我在这里就不累述了。