權(quán)限管理工具的使用方法
2024-07-21 02:17:09
供稿:網(wǎng)友
 
權(quán)限管理工具的使用
在當(dāng)今商業(yè)軟件的開發(fā)中有一項(xiàng)功能是必不可少的,這就是權(quán)限工具,想必大家對(duì)權(quán)限這個(gè)詞不會(huì)太陌生,應(yīng)為在我們身邊的很多軟件上都用到了權(quán)限,比如說(shuō)最常見的windows操作系統(tǒng),就使用到了權(quán)限,但是在實(shí)際的開發(fā)過(guò)程中,權(quán)限是個(gè)相當(dāng)麻煩的東西。大家都在尋找一種簡(jiǎn)易的權(quán)限管理方式,這個(gè)時(shí)候我們發(fā)現(xiàn)了cg.security這個(gè)組件,這是一個(gè)非常優(yōu)秀的功能權(quán)限管理組件,它可以讓我們非常簡(jiǎn)便的來(lái)控制軟件的權(quán)限。
使用cg.security你可以任意添加刪除權(quán)限、角色和權(quán)限。可以通過(guò)大多數(shù)的權(quán)限管理方式給用戶賦予角色或直接給用戶賦予權(quán)限。
好了,簡(jiǎn)短介紹了cg.security的功能后下面將為大家來(lái)講解下該組件的用法。在講解之前請(qǐng)首先到http://www.codeproject.com/csharp/cgsecurity.asp上下載該組件。
下面的講解會(huì)分兩個(gè)部分:
第一部分將講解該類庫(kù)中常見的一些方法屬性的用法。第二部分通過(guò)一個(gè)小demo,給大家一個(gè)感性的認(rèn)識(shí),讓大家了解在實(shí)際開發(fā)中如何使用cg.security。
 
一、 類庫(kù)的常用方法
在這個(gè)組件中用了六個(gè)類來(lái)分別實(shí)現(xiàn)了用戶管理、權(quán)限管理和角色管理。
usermanager(用戶管理類):該類提供了添加、刪除和查找用戶的方法。
rolemanager(角色管理類):該類提供了添加、刪除和查找角色的方法。
rightmanager(權(quán)限管理類):該類提供了添加、刪除和修改權(quán)限的方法。
userrightmanager(用戶權(quán)限管理類):該類的作用是使用戶和權(quán)限關(guān)聯(lián),也提供了增、刪、查的功能,使用此類,可以為某個(gè)用戶直接賦予權(quán)限。
userrolemanager(用戶角色管理類):該類和上面的userrightmanager相似,也提供了相似的功能,所不同的是該類是把用戶和角色進(jìn)行關(guān)聯(lián)。
rolerightmanager(角色權(quán)限管理類)該類提供了角色和權(quán)限關(guān)聯(lián)的功能。
 
在介紹了上述六個(gè)類后,下面還要為大家介紹在實(shí)際開發(fā)中會(huì)用到的一個(gè)類。
securitymanager.cs 類,該類提供了登陸驗(yàn)證(authenticate)和獲得該用戶權(quán)限列表(effectiverights)的功能。使用該類我們可以判斷用戶的合法性并且能得到當(dāng)前用戶的權(quán)限列表。
 
上面介紹了權(quán)限管理組件中幾個(gè)常見類的功能。讓大家對(duì)權(quán)限管理組件有一個(gè)全面的了解,下面的一部分我將一步一步做出一個(gè)小demo讓大家對(duì)這個(gè)組件有一個(gè)感性的認(rèn)識(shí)。ok,偶們進(jìn)入下一環(huán)節(jié)吧。
 
二、 做一個(gè)小demo來(lái)演示如何使用這個(gè)權(quán)限工具
 
1. 首先我們要從網(wǎng)上下載該組件,該組件可以從http://www.codeproject.com/csharp/cgsecurity.asp上找到,在下載后在bin/release目錄下找到cg.security.dll文件。
 
2.新建一個(gè)解決方案cgtest。
 
3.然后在form1上添加12個(gè)按鈕分別為btnadduser、btndeluser、btnaddrole、btndelrole、btnaddright、btndelright、btnadduserrole、btndeluserrole、btnaddroleright、btndelroleright、btnadduserright、btndeluserright。
 上述12個(gè)按鈕大家從字面上都可以了解到是什么含義。在這里還要添加一個(gè)checkbox,命名為cbuserright。
 
4.在添加完按鈕后我們?cè)僭趂orm1上添加6個(gè)datagrid分別命名為dguser、dgrole、dgright、dgroleright、dguserrole、dguserright。這六個(gè)按鈕分別顯示出了6個(gè)數(shù)據(jù)表里面的數(shù)據(jù)。經(jīng)過(guò)3、4兩個(gè)步驟后我們的程序的管理權(quán)限部分就添加完成了,但是做了管理權(quán)限后我們?nèi)绾蝸?lái)使用這個(gè)權(quán)限呢?下面一步將向大家介紹如何來(lái)控制權(quán)限。
 
5.我們可以在界面上添加兩個(gè)個(gè)按鈕btntestall,btntestsingle。btntestall是所有人都能操作的,但是btntestsingle則是擁有某個(gè)權(quán)限的人才能操作的。
 
6.上面添加的是我們的主界面,下面我們還要添加一個(gè)用來(lái)輸入用戶名密碼等信息的輔助界面,在工程上添加一個(gè)新的windows窗體,然后命名為formvalue。當(dāng)窗體新建好后在窗體上新建textbox、button一樣兩個(gè)。textbox分別命名為txtname,txtpwd,button分別命名為btnok,btncancel。并且把btnok的dialogresult屬性設(shè)置為ok,btncancel的dialogresult屬性設(shè)置為cancel。窗體設(shè)置完后我們?cè)诖a中添加兩個(gè)屬性
 public string uid
 {
 get{return txtname.text.trim();}
 }
 
 public string pwd
  {
 get{return txtpwd.text.trim();}
 }
 
7.首先在項(xiàng)目種引用cg.security.dll這個(gè)組件。在form1上導(dǎo)入cg.security和cg.security.principal這兩個(gè)命名空間。
using cg.security;
using cg.security.principal;
 
8. 在添加完引用后。我們還有兩個(gè)東西要準(zhǔn)備,數(shù)據(jù)庫(kù)和程序的配置文件配置文件,數(shù)據(jù)庫(kù)大家可以在該組件demo的database目錄下找到security.mdb這個(gè)文件,把該文件copy到我們cgtest項(xiàng)目的debug目錄下。搞定數(shù)據(jù)庫(kù)后下面我們還要添加一個(gè)配置文件,那么首先我們添加一個(gè)新的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>
 上述的配置文件大家可以看到是連接數(shù)據(jù)庫(kù)的一些信息,他使用到了cg.security.data.configuration.datasettingshandler這個(gè)類來(lái)讀取數(shù)據(jù)庫(kù)信息,在配置文件中我們可以很清楚的看到連接字符串,該配置文件使用oledb連接到當(dāng)前目錄下的access數(shù)據(jù)庫(kù)。所以我們把數(shù)據(jù)庫(kù)放到bin/dubug目錄下。當(dāng)一切配置都完成了的時(shí)候,我們就開始實(shí)現(xiàn)具體的代碼了。
 
9. 首先我們要實(shí)現(xiàn)添加刪除用戶、角色權(quán)限的代碼。
首先我們來(lái)看看怎么添加一個(gè)用戶
 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個(gè)參數(shù)用戶名和密碼,當(dāng)調(diào)用了該方法后我們就可以創(chuàng)建一個(gè)用戶了。
 
那么有添加肯定就有刪除的方法了我們?cè)赽tndeluser的單擊事件中實(shí)現(xiàn)如下的代碼。
 private void btndeluser_click(object sender, system.eventargs e)
 {
 usermanager.delete((int32)usermanager.findall().tables[0].rows[dguser.currentrowindex]["user_id"]);
//刷新dg的顯示
 reflash();
 }
大家可以看到當(dāng)刪除的時(shí)候傳入的是一個(gè)整型數(shù),該整型數(shù)是某個(gè)用戶的id值,該值在數(shù)據(jù)庫(kù)里面是自動(dòng)增長(zhǎng)的。我們可以通過(guò)用戶名來(lái)得到該用戶的id值。
至于角色增刪和權(quán)限增刪與上面的示例大致相同,所不同的是角色增刪使用的是rolemanager類,權(quán)限增刪使用的是rightmanager類,那么我在這里就不累述該過(guò)程了,所用的方法名和用戶管理里面的方法名相同。
 
10.上面大家可以看到我用了一個(gè)reflash方法,該方法是用來(lái)更新datagrid 上顯示的數(shù)據(jù)。應(yīng)為我們每做一個(gè)操作數(shù)據(jù)庫(kù)中的數(shù)據(jù)都要改,所以我為了方便起見把他封裝到一個(gè)方法里面了,該方法的代碼如下:
 dguser.datasource = usermanager.findall().tables[0];
 dgright.datasource = rightmanager.findall().tables[0];
 dgrole.datasource = rolemanager.findall().tables[0];
上面三句代碼是不是很簡(jiǎn)單,在上面的過(guò)程中我分別使用到了3個(gè)不同類的findall方法,該方法是查詢所有的信息,返回一個(gè)dataset,所以我們把他的tables[0]作為數(shù)據(jù)源綁定到datagrid上。
 
11. 上面的步驟講述了怎么去增刪改權(quán)限、用戶、角色等,下面我們將了解如何管理他們之間的關(guān)系。
 //關(guān)聯(lián)用戶和角色
 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"]);
 }
 
 //刪除用戶角色的關(guān)聯(lián)
 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"]);
 }
 
 //關(guān)聯(lián)角色權(quán)限
 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"]);
 }
 
 //刪除角色權(quán)限的關(guān)聯(lián)
 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"]);
 }
 
 //關(guān)聯(lián)用戶權(quán)限-指是否讓用戶某一權(quán)限
 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);
 }
 
 //刪除用戶權(quán)限關(guān)聯(lián)
 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"]);
 }
 
上述代碼講述的是如何建立他們之間的關(guān)系,其實(shí)每個(gè)類的增加和刪除的方法大致相同,唯一有一個(gè)不同的就是userrightmanager.create方法,該方法接受3個(gè)參數(shù),最后一個(gè)參數(shù)是是否啟用該權(quán)限的標(biāo)志,它是一個(gè)bool值的變量。還記得我們前面添加了一個(gè)checkbox嗎。這個(gè)時(shí)候我們傳入的參數(shù)就是checkbox的值。如果你要啟用該權(quán)限就把checkbox鉤上。
 
12.我們?cè)诮缑嫔霞尤肓?個(gè)datagrid,我們目前只用了3個(gè),下面我們將使用另外三個(gè)來(lái)顯示他們之間的關(guān)系。
 首先我們?cè)赿guser的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];
上述代碼的意思是當(dāng)點(diǎn)擊了某一用戶的時(shí)候就可以看到該用戶所擁有的角色和權(quán)限。
 
 下面還有一個(gè)就是roleright(角色和權(quán)限的關(guān)聯(lián)),我們想知道某個(gè)角色擁有哪些權(quán)限怎么辦呢?有辦法,我們可以通過(guò)rolerightmanager類來(lái)查找某一角色擁有哪些權(quán)限。在dgrole的currentcellchanged事件中添加如下的代碼:
 dgroleright.datasource = null;
 dgroleright.datasource = rolerightmanager.findbyrole((int32)rolemanager.findall().tables[0].rows[dgrole.currentrowindex]["role_id"]).tables[0];
上述代碼的意思是當(dāng)點(diǎn)擊了某一角色就可以知道該角色擁有哪些權(quán)限了。
 
上述步驟說(shuō)明了如何管理權(quán)限,下面我們將了解如何使用這些權(quán)限。
 
13.首先我們?cè)趂ormload事件中添加如下代碼:
 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();
 
大家看到上述代碼就是一個(gè)權(quán)限管理的典型應(yīng)用,我將為大家一步一步講解這段代碼。
首先我們可以看到這樣一段代碼
formvalue fv = new formvalue();
 if(fv.showdialog(this)!=dialogresult.ok)
 {
 this.close();
 return;
 }
該代碼是首先實(shí)例化一個(gè)輸入用戶名密碼的窗體,然后判斷用戶是否點(diǎn)擊了ok,如果沒有點(diǎn)擊ok就退出程序。
 
if(!securitymanager.authenticate(fv.uid,fv.pwd))
 {
 messagebox.show("非法用戶");
 this.close();
 return;
 }
 這段代碼就是精華之所在了,securitymanager類是一個(gè)用戶驗(yàn)證類,在這里我們調(diào)用了它的authenticate方法,該方法接受兩個(gè)參數(shù),用戶名和密碼。并返回一個(gè)bool值,借此我們可以判斷該用戶是否是合法用戶。
system.appdomain.currentdomain.setthreadprincipal(
 new customprincipal(new customidentity("admin"))
 該句的意思是把某一用戶綁定到線程的主對(duì)象上,我在這里默認(rèn)使用admin來(lái)綁定,應(yīng)為在這個(gè)組件中只有admin這個(gè)用戶才能做添加刪除用戶等操作。
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;
 }
 }
上面一段代碼就是講如何使用權(quán)限了。
首先我們調(diào)用usermanager.findbyusername方法得到一個(gè)datareader對(duì)象(該方法是通過(guò)用戶名來(lái)查找用戶的信息),然后讀取datareader對(duì)象取得當(dāng)前用戶的id。
 然后調(diào)用securitymanager.effectiverights方法列出該用戶擁有的所有權(quán)限。當(dāng)?shù)玫皆撚脩舻乃袡?quán)限后我們利用一個(gè)foreach循環(huán)來(lái)遍歷該用戶的權(quán)限,并判斷該用戶有沒有test 1權(quán)限,如果有就讓該用戶使用btntest按鈕,反之則不讓使用。
 
 
多看偶一分鐘:
 經(jīng)過(guò)上面的步驟一個(gè)權(quán)限管理demo就完成了,你可以使用admin和guest兩個(gè)用戶登陸看看,你可以很清楚的看到admin可以操作btntestall和btntest按鈕,但是guest用戶只能操作btntestall按鈕,這樣就可以通過(guò)用戶名來(lái)判斷用戶權(quán)限了。
回顧上面的文檔,我首先為大家介紹了該組件的常用類和常用方法,在第二部分我們通過(guò)一個(gè)實(shí)例來(lái)實(shí)現(xiàn)如何在程序中使用這些權(quán)限。在這個(gè)組件中還有更改用戶密碼等方法我在這里就不一一介紹了(應(yīng)為很簡(jiǎn)單了:))。如果大家有什么不明白的地方可以和偶交流。好了,該吃飯了,都12點(diǎn)多了 ^_^。