ASP.NET Identity 使用 RoleManager 進(jìn)行角色管理 (VS2013RC)
注:本文系作者原創(chuàng),但可隨意轉(zhuǎn)載。
最近做一個(gè)Web平臺(tái)系統(tǒng),系統(tǒng)包含3個(gè)角色,“管理員, 企業(yè)用戶, 評(píng)審專家”, 分別有不同的功能。一直以來(lái)都是使用微軟封裝好的Microsoft.AspNet.Identity.dll程序集來(lái)進(jìn)行身份驗(yàn)證和角色控制。
在MVC項(xiàng)目中,生成項(xiàng)目結(jié)構(gòu)中,甚至已經(jīng)包含了創(chuàng)建好的AccountController,可以直接使用進(jìn)行賬號(hào)管理。不過(guò)最近一次使用Identity功能,是在Visual Studio 2013的Preview版本中,現(xiàn)在升級(jí)到了RC和Ultimate版,整個(gè)程序集已經(jīng)徹底翻新了。想進(jìn)行角色控制,我了個(gè)擦發(fā)現(xiàn)Account控制器中初始化的一個(gè)控制類UserManager已經(jīng)根本不包含角色控制的方法了。。。于是乎,開(kāi)始上網(wǎng)查資料,搜索"ASP.NET Identity Role(Manager)",但發(fā)現(xiàn)大部分都是零幾年的文章了,微軟官方博客里倒是看到了相關(guān)的講解,很詳細(xì),但尼瑪是Preview版本的啊,后面有人追問(wèn)正式版的也沒(méi)有答復(fù)。于是懶得再找了,打開(kāi)dotPeek對(duì)整個(gè)程序集進(jìn)行反編譯,看一下內(nèi)部代碼到底是如何實(shí)現(xiàn)角色控制的。
先看一下本文問(wèn)題背景的具體情況。下面有一段代碼介紹了AccountController的構(gòu)造方法,其中的LCDEUser,LCDEDbContext是我定義的繼承了IdentityUser和DbContext的應(yīng)用程序的賬號(hào)實(shí)體類和數(shù)據(jù)庫(kù)上下文類,由于Identity本身是基于EntityFramework來(lái)實(shí)現(xiàn)的。這里就不再介紹EF,假定您對(duì)EF已經(jīng)了解。Account控制器的構(gòu)造方法中初始化了一個(gè)UserManager管理類,這個(gè)類可以進(jìn)行創(chuàng)建賬號(hào),修改密碼。。。等各種賬號(hào)管理功能,還有一個(gè)方法叫AddToRole(..),意思是把一個(gè)賬號(hào)(User)與一個(gè)角色(Role)進(jìn)行關(guān)聯(lián),關(guān)鍵是現(xiàn)在根本就不存在任何角色,UserManager類也不提供創(chuàng)建角色的方法。

Identity功能主要由3個(gè)程序集組成。Microsoft.AspNet.Identity.Core / EntityFramework / Owin 其中Owin和第三方登陸相關(guān),此處我暫時(shí)用不到就先不看了。
用反編譯工具打開(kāi)程序集后如圖1。
圖1 圖2
圖2中是Identity自動(dòng)生成的幾張數(shù)據(jù)庫(kù)表,看起來(lái)和左邊程序中的幾個(gè)類名一致。打開(kāi)一看果然 左側(cè)程序集中的IdentityRole, IdentityUser, IdentityUserClaim, IdentityUserLogin, IdentityUserRole分別是實(shí)體模型類,包含的屬性和數(shù)據(jù)庫(kù)中的表的字段一致。其中的EntityStore作為泛型類提供了幾個(gè)基本操作Create,Delete,GetById。 RoleStore<T>用來(lái)操作和角色控制相關(guān)的實(shí)體數(shù)據(jù),UserStore<T>用來(lái)操作和賬號(hào)相關(guān)的實(shí)體數(shù)據(jù),其中提供了諸多的方法,而這兩個(gè)類的訪問(wèn)權(quán)限又是Public的,可以認(rèn)為只是使用這兩個(gè)類也可以進(jìn)行一些數(shù)據(jù)實(shí)體的訪問(wèn)和存儲(chǔ)操作。
圖3
圖3是使用反編譯工具打開(kāi)Core.dll后看到的內(nèi)部構(gòu)造。其中東西頗多不一一介紹,主要介紹一下我們要用到的。打開(kāi)后發(fā)現(xiàn)其中有一個(gè)UserManager類,這不正是我們用來(lái)進(jìn)行賬號(hào)管理的類么,還有一個(gè)RoleManager類,肯定就是進(jìn)行角色控制的了,可是沒(méi)有相關(guān)文檔,項(xiàng)目的初始架構(gòu)中又沒(méi)有幫我們初始化這個(gè)東西,而它的構(gòu)造函數(shù)又有點(diǎn)復(fù)雜(主要是傳入?yún)?shù)中還要new 一些RoleStore, DbContext之類的東西),不打開(kāi)看看相關(guān)代碼或文檔,想要直接使用還是有點(diǎn)困難撒,主要是萬(wàn)一用錯(cuò)了折騰起來(lái)太費(fèi)時(shí)間。
打開(kāi)RoleManager類后看到這么一段代碼:

它的構(gòu)造函數(shù)需要傳遞一個(gè)RoleStore進(jìn)去,實(shí)際上RoleManager就是提供了比RoleStore更多方法,方法名稱更具可讀性,更方便編程的一個(gè)類,因此不推薦直接使用RoleStore來(lái)進(jìn)行數(shù)據(jù)的訪問(wèn)及存儲(chǔ)。而RoleStore的構(gòu)造方法需要傳遞一個(gè)DbContext給它,搞清楚怎么初始化它,就可以正式使用了。下面參考一段,對(duì)數(shù)據(jù)庫(kù)進(jìn)行初始化,建立種子數(shù)據(jù)的代碼,其中包括的對(duì)UserManager和RoleManager的具體使用。

在使用中還有一些其他需要注意的事項(xiàng),在MVC中,通常我會(huì)做一個(gè)BaseController,其中包含了dbcontext,usermanager的實(shí)例創(chuàng)建, 假如首先實(shí)例化一個(gè)dbcontext,再去實(shí)例化一個(gè)usermanager,由于usermanager的實(shí)例化需要傳入一個(gè)dbcontext,我嘗試將實(shí)例化好的dbcontext實(shí)體傳入,在本機(jī)運(yùn)行時(shí),沒(méi)有問(wèn)題,但發(fā)布到服務(wù)器上時(shí),會(huì)出現(xiàn)DataReader的使用沖突,于是在usermanager進(jìn)行構(gòu)造時(shí),要傳入一個(gè)new DbContext()給它。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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