權限管理工具的使用
在當今商業(yè)軟件的開發(fā)中有一項功能是必不可少的 , 這就是權限工具 , 想必大家對權限這個詞不會太陌生 , 應為在我們身邊的很多軟件上都用到了權限 , 比如說最常見的 Windows 操作系統(tǒng),就使用到了權限,但是在實際的開發(fā)過程中,權限是個相當麻煩的東西。大家都在尋找一種簡易的權限管理方式,這個時候我們發(fā)現(xiàn)了 CG . Security 這個組件,這是一個非常優(yōu)秀的功能權限管理組件,它可以讓我們非常簡便的來控制軟件的權限。
使用 CG . Security 你可以任意添加刪除權限、角色和權限。可以通過大多數(shù)的權限管理方式給用戶賦予角色或直接給用戶賦予權限。
好了,簡短介紹了 CG . Security 的功能后下面將為大家來講解下該組件的用法。在講解之前請首先到 http://www.codeproject.com/csharp/CGSecurity.asp 上下載該組件。
下面的講解會分兩個部分:
第一部分將講解該類庫中常見的一些方法屬性的用法。第二部分通過一個小 DEMO ,給大家一個感性的認識,讓大家了解在實際開發(fā)中如何使用 CG . Security 。
一、 類庫的常用方法
在這個組件中用了六個類來分別實現(xiàn)了用戶管理、權限管理和角色管理。
UserManager (用戶管理類):該類提供了添加、刪除和查找用戶的方法。
RoleManager (角色管理類):該類提供了添加、刪除和查找角色的方法。
RightManager (權限管理類):該類提供了添加、刪除和修改權限的方法。
UserRightManager (用戶權限管理類):該類的作用是使用戶和權限關聯(lián),也提供了增、刪、查的功能,使用此類,可以為某個用戶直接賦予權限。
UserRoleManager (用戶角色管理類):該類和上面的 UserRightManager 相似,也提供了相似的功能,所不同的是該類是把用戶和角色進行關聯(lián)。
RoleRightManager (角色權限管理類)該類提供了角色和權限關聯(lián)的功能。
在介紹了上述六個類后,下面還要為大家介紹在實際開發(fā)中會用到的一個類。
SecurityManager.cs 類,該類提供了登陸驗證( Authenticate )和獲得該用戶權限列表( EffectiveRights )的功能。使用該類我們可以判斷用戶的合法性并且能得到當前用戶的權限列表。
上面介紹了權限管理組件中幾個常見類的功能。讓大家對權限管理組件有一個全面的了解,下面的一部分我將一步一步做出一個小 DEMO 讓大家對這個組件有一個感性的認識。 OK ,偶們進入下一環(huán)節(jié)吧。
二、 做一個小 Demo 來演示如何使用這個權限工具
一、 做一個小 Demo 來演示如何使用這個權限工具
1. 我們在這個 Demo 中會實現(xiàn)數(shù)據(jù)權限和功能權限兩種權限管理功能。首先我們要從網(wǎng)上下載該組件,該組件可以從 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 經(jīng)過上述三個步驟之后我們的界面工作就完成了,下面我們將開始實現(xiàn)他們的具體功能 . 。
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 >
上述的配置文件大家可以看到是連接數(shù)據(jù)庫的一些信息,他使用到了 CG.Security.Data.Configuration.DataSettingsHandler 這個類來讀取數(shù)據(jù)庫信息,在配置文件中我們可以很清楚的看到連接字符串,該配置文件使用 Oledb 連接到指定目錄下的 Access 數(shù)據(jù)庫。應為我是放在 F 盤的,這里大家要根據(jù)自己數(shù)據(jù)庫存放的實際位置來。當一切配置都完成了的時候,我們就開始實現(xiàn)具體的代碼了。
8 .進入應用程序第一步肯定就是要驗證當前用戶的合法性啦, ok 那么我們首先從窗體的加載事件開始講起:
首先我們要在定義一個全局的 string 數(shù)組 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 ));
// 循環(huán)每個權限
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 方法,該方法接受兩個參數(shù),用戶名和密碼。并返回一個 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 方法列出該用戶擁有的所有權限保存在一個字符串數(shù)組里面。
// 循環(huán)每個權限
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 ;
}
}
在這里我們剛才得到的權限數(shù)組,然后在判斷當該用戶是否擁有某個功能權限,例如 Test 1 權限的時候就讓他使用 Test1 菜單和 btnTest1 按鈕等。
這個時候大家可以編譯程序,拿 admin 用戶進系統(tǒng)和拿 user 進系統(tǒng)有什么不同之處呢?呵呵,大家可以看大使用 User 進去的時候菜單 Test1 和 Test4 不見了,還有就是 btnTest1 按鈕變成灰色的了。
9. 上面,我們講述了怎么使用功能權限,接下來,我將利用一個主從表的示例程序來為大家講解如何使用數(shù)據(jù)權限,我們最后要實現(xiàn)的效果是擁有 Test4 權限的用戶可以即看到主表又看到從表,反之則只能看到主表。
好了,首先我們在 bin/debug 目錄下添加一個 orders.mdb 數(shù)據(jù)庫,然后在里面分別建 2 張表 orders 和 orderlist 。
Orders 表字段如下
ordered 自動編號
orderType 文本 (訂單類別)
orderTimer 日期時間 (發(fā)生時間)
orderlist 表字段如下
orderListID 自動編號
orderid 數(shù)字 (主表的 ID )
ProdName 文本 (商品名稱)
Count 數(shù)字 (數(shù)量)
當大家把上面的表格式建立好了以后把 orders 和 orderlist 表的 orderid 值進行關聯(lián)。
上述步驟做完了后就往數(shù)據(jù)庫里面添加幾條數(shù)據(jù)。
OK 數(shù)據(jù)庫準備好了,我們也該看看怎么來實現(xiàn)了,在 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, "<place w:st="on">Main</place>" );
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)
{
// 如果當用戶擁有該權限的時候可以看到從表里面的內(nèi)容
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 = " 數(shù)量 " ;
dtL . GridColumnStyles . Add(dclName);
dtL . GridColumnStyles . Add(dclCount);
dtL . MappingName = ds . Tables[ 1 ] . TableName;
dgView . TableStyles . Add(dtL);
break ;
}
}
上面的代碼很簡單,都是常用的數(shù)據(jù)庫操作,我要講解的是便利循環(huán)的地方。
foreach ( string stra in str)
{
// 如果當用戶擁有該權限的時候可以看到從表里面的內(nèi)容
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" ]);
……
}
<span
發(fā)表評論
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

評論