权限管理工具的使用
在当今商业软件的开发中有一项功能是必不可少的,这就是权限工具,想必大家对权限这个词不会太陌生,应为在我们身边的很多软件上都用到了权限,比如说最常见的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来演示如何使用这个权限工具
1. 首先我们要从网上下载该组件,该组件可以从http://www.codeproject.com/csharp/CGSecurity.asp上找到,在下载后在bin/release目录下找到CG.Security.dll文件。
2.新建一个解决方案CGTest。
3.然后在Form1上添加12个按钮分别为btnAddUser、btnDelUser、btnAddRole、btnDelRole、btnAddRight、btnDelRight、btnAddUserRole、btnDelUserRole、btnAddRoleRight、btnDelRoleRight、btnAddUserRight、btnDelUserRight。
上述12个按钮大家从字面上都可以了解到是什么含义。在这里还要添加一个checkbox,命名为cbUserRight。
4.在添加完按钮后我们再在Form1上添加6个DataGrid分别命名为dgUser、dgRole、dgRight、dgRoleRight、dgUserRole、dgUserRight。这六个按钮分别显示出了6个数据表里面的数据。经过3、4两个步骤后我们的程序的管理权限部分就添加完成了,但是做了管理权限后我们如何来使用这个权限呢?下面一步将向大家介绍如何来控制权限。
5.我们可以在界面上添加两个个按钮btnTestAll,btnTestSingle。btnTestAll是所有人都能操作的,但是btnTestSingle则是拥有某个权限的人才能操作的。
6.上面添加的是我们的主界面,下面我们还要添加一个用来输入用户名密码等信息的辅助界面,在工程上添加一个新的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();}
}
7.首先在项目种引用CG.Security.dll这个组件。在FORM1上导入CG.Security和CG.Security.Principal这两个命名空间。
using CG.Security;
using CG.Security.Principal;
8. 在添加完引用后。我们还有两个东西要准备,数据库和程序的配置文件配置文件,数据库大家可以在该组件Demo的Database目录下找到security.mdb这个文件,把该文件Copy到我们CGTest项目的Debug目录下。搞定数据库后下面我们还要添加一个配置文件,那么首先我们添加一个新的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;User ID=Admin;Data Source=security.mdb;Mode=Share Deny None;Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt atabase=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False"¸
/>
</installedAssembly>
</runtimeSetup>
</CG.Security.Data>
</configuration>
上述的配置文件大家可以看到是连接数据库的一些信息,他使用到了CG.Security.Data.Configuration.DataSettingsHandler这个类来读取数据库信息,在配置文件中我们可以很清楚的看到连接字符串,该配置文件使用Oledb连接到当前目录下的Access数据库。所以我们把数据库放到bin/dubug目录下。当一切配置都完成了的时候,我们就开始实现具体的代码了。
9. 首先我们要实现添加删除用户、角色权限的代码。
首先我们来看看怎么添加一个用户
private void btnAddUser_Click(object sender, System.EventArgs e)
{
FormValue fv = new FormValue();
if(fv.ShowDialog(this)!=DialogResult.OK)
{
return;
}
UserManager.Create(fv.UID,fv.PWD);
Reflash();
}
上述代码使用了UserManager类的Create方法,该方法接受2个参数用户名和密码,当调用了该方法后我们就可以创建一个用户了。
那么有添加肯定就有删除的方法了我们在btnDelUser的单击事件中实现如下的代码。
private void btnDelUser_Click(object sender, System.EventArgs e)
{
UserManager.Delete((Int32)UserManager.FindAll().Tables[0].Rows[dgUser.CurrentRowIndex]["user_id"]);
//刷新dg的显示
Reflash();
}
大家可以看到当删除的时候传入的是一个整型数,该整型数是某个用户的ID值,该值在数据库里面是自动增长的。我们可以通过用户名来得到该用户的id值。
至于角色增删和权限增删与上面的示例大致相同,所不同的是角色增删使用的是RoleManager类,权限增删使用的是RightManager类,那么我在这里就不累述该过程了,所用的方法名和用户管理里面的方法名相同。
10.上面大家可以看到我用了一个Reflash方法,该方法是用来更新datagrid 上显示的数据。应为我们每做一个操作数据库中的数据都要改,所以我为了方便起见把他封装到一个方法里面了,该方法的代码如下:
dgUser.DataSource = UserManager.FindAll().Tables[0];
dgRight.DataSource = RightManager.FindAll().Tables[0];
dgRole.DataSource = RoleManager.FindAll().Tables[0];
上面三句代码是不是很简单,在上面的过程中我分别使用到了3个不同类的FindAll方法,该方法是查询所有的信息,返回一个DataSet,所以我们把他的Tables[0]作为数据源绑定到datagrid上。
11. 上面的步骤讲述了怎么去增删改权限、用户、角色等,下面我们将了解如何管理他们之间的关系。
//关联用户和角色
private void btnAddUserRole_Click(object sender, System.EventArgs e)
{
UserRoleManager.Create((Int32)UserManager.FindAll().Tables[0].Rows[dgUser.CurrentRowIndex]["user_id"],(Int32)RoleManager.FindAll().Tables[0].Rows[dgRole.CurrentRowIndex]["role_id"]);
}
//删除用户角色的关联
private void btnDelUserRole_Click(object sender, System.EventArgs e)
{
UserRoleManager.Delete((Int32)UserManager.FindAll().Tables[0].Rows[dgUser.CurrentRowIndex]["user_id"],(Int32)RoleManager.FindAll().Tables[0].Rows[dgRole.CurrentRowIndex]["role_id"]);
}
//关联角色权限
private void btnAddRoleRight_Click(object sender, System.EventArgs e)
{
RoleRightManager.Create((Int32)RoleManager.FindAll().Tables[0].Rows[dgRole.CurrentRowIndex]["role_id"],(Int32)RightManager.FindAll().Tables[0].Rows[dgRight.CurrentRowIndex]["right_id"]);
}
//删除角色权限的关联
private void btnDelRoleRight_Click(object sender, System.EventArgs e)
{
RoleRightManager.Delete((Int32)RoleManager.FindAll().Tables[0].Rows[dgRole.CurrentRowIndex]["role_id"],(Int32)RightManager.FindAll().Tables[0].Rows[dgRight.CurrentRowIndex]["right_id"]);
}
//关联用户权限-指是否让用户某一权限
private void btnAddUserRight_Click(object sender, System.EventArgs e)
{
UserRightManager.Create((Int32)UserManager.FindAll().Tables[0].Rows[dgUser.CurrentRowIndex]["user_id"],(Int32)RightManager.FindAll().Tables[0].Rows[dgRight.CurrentRowIndex]["right_id"],cbUserRight.Checked);
}
//删除用户权限关联
private void btnDelUserRight_Click(object sender, System.EventArgs e)
{
UserRightManager.Delete((Int32)UserManager.FindAll().Tables[0].Rows[dgUser.CurrentRowIndex]["user_id"],(Int32)RightManager.FindAll().Tables[0].Rows[dgRight.CurrentRowIndex]["right_id"]);
}
上述代码讲述的是如何建立他们之间的关系,其实每个类的增加和删除的方法大致相同,唯一有一个不同的就是UserRightManager.Create方法,该方法接受3个参数,最后一个参数是是否启用该权限的标志,它是一个bool值的变量。还记得我们前面添加了一个checkbox吗。这个时候我们传入的参数就是checkbox的值。如果你要启用该权限就把checkbox钩上。
12.我们在界面上加入了6个datagrid,我们目前只用了3个,下面我们将使用另外三个来显示他们之间的关系。
首先我们在dgUser的CurrentCellChanged事件里面写:
dgUserRight.DataSource = null;
dgUserRole.DataSource = null;
dgUserRole.DataSource = UserRoleManager.FindByUser((Int32)UserManager.FindAll().Tables[0].Rows[dgUser.CurrentRowIndex]["user_id"]).Tables[0];
dgUserRight.DataSource = UserRightManager.FindByUser((Int32)UserManager.FindAll().Tables[0].Rows[dgUser.CurrentRowIndex]["user_id"]).Tables[0];
上述代码的意思是当点击了某一用户的时候就可以看到该用户所拥有的角色和权限。
下面还有一个就是RoleRight(角色和权限的关联),我们想知道某个角色拥有哪些权限怎么办呢?有办法,我们可以通过RoleRightManager类来查找某一角色拥有哪些权限。在dgRole的CurrentCellChanged事件中添加如下的代码:
dgRoleRight.DataSource = null;
dgRoleRight.DataSource = RoleRightManager.FindByRole((Int32)RoleManager.FindAll().Tables[0].Rows[dgRole.CurrentRowIndex]["role_id"]).Tables[0];
上述代码的意思是当点击了某一角色就可以知道该角色拥有哪些权限了。
上述步骤说明了如何管理权限,下面我们将了解如何使用这些权限。
13.首先我们在formload事件中添加如下代码:
FormValue fv = new FormValue();
if(fv.ShowDialog(this)!=DialogResult.OK)
{
this.Close();
return;
}
if(!SecurityManager.Authenticate(fv.UID,fv.PWD))
{
MessageBox.Show("非法用户");
this.Close();
return;
}
System.AppDomain.CurrentDomain.SetThreadPrincipal(
new CustomPrincipal(new CustomIdentity("admin"))
);
OleDbDataReader dataread = (OleDbDataReader)UserManager.FindByUserName(fv.UID);
string[] str= null;
dataread.Read();
str = SecurityManager.EffectiveRights(dataread.GetInt32(0));
btnTest.Enabled = false;
foreach(string strSingle in str)
{
if(strSingle=="Test 1")
{
btnTest.Enabled = true;
break;
}
}
Reflash();
大家看到上述代码就是一个权限管理的典型应用,我将为大家一步一步讲解这段代码。
首先我们可以看到这样一段代码
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("admin"))
该句的意思是把某一用户绑定到线程的主对象上,我在这里默认使用Admin来绑定,应为在这个组件中只有Admin这个用户才能做添加删除用户等操作。
OleDbDataReader dataread = (OleDbDataReader)UserManager.FindByUserName(fv.UID);
string[] str= null;
while(dataread.Read())
{
str = SecurityManager.EffectiveRights(dataread.GetInt32(0));
break;
}
btnTest.Enabled = false;
foreach(string strSingle in str)
{
if(strSingle=="Test 1")
{
btnTest.Enabled = true;
break;
}
}
上面一段代码就是讲如何使用权限了。
首先我们调用UserManager.FindByUserName方法得到一个DataReader对象(该方法是通过用户名来查找用户的信息),然后读取DataReader对象取得当前用户的ID。
然后调用SecurityManager.EffectiveRights方法列出该用户拥有的所有权限。当得到该用户的所有权限后我们利用一个foreach循环来遍历该用户的权限,并判断该用户有没有Test 1权限,如果有就让该用户使用btnTest按钮,反之则不让使用。
多看偶一分钟:
经过上面的步骤一个权限管理Demo就完成了,你可以使用Admin和guest两个用户登陆看看,你可以很清楚的看到Admin可以操作btntestall和btntest按钮,但是guest用户只能操作btntestall按钮,这样就可以通过用户名来判断用户权限了。
回顾上面的文档,我首先为大家介绍了该组件的常用类和常用方法,在第二部分我们通过一个实例来实现如何在程序中使用这些权限。在这个组件中还有更改用户密码等方法我在这里就不一一介绍了(应为很简单了:))。如果大家有什么不明白的地方可以和偶交流。好了,该吃饭了,都12点多了 ^_^。