对DbRuleAuthorizationProvider的修改
????有用過Security Application Block(以下簡稱SAB)的朋友都知道,它的權(quán)限規(guī)則是直接存在配置文件中,并沒有提供存在數(shù)據(jù)庫的實(shí)現(xiàn)形式,大家也都知道已經(jīng)有人對它進(jìn)行了擴(kuò)展,提供了一個(gè)叫DBRulesAuthorizationProvider的Provider。(http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=c0b0ce8e-1b72-44ab-b300-f369eb18664a)。對于我來說,這是一個(gè)非常不錯(cuò)的Provider,現(xiàn)在都它了??墒菂s存在一個(gè)問題,每次驗(yàn)證授權(quán)的時(shí)候都去讀取數(shù)據(jù)庫,特別是當(dāng)我想得到某個(gè)或某個(gè)角色所具有的所有權(quán)限時(shí)(SAB使用的是邏輯表達(dá)式的形式進(jìn)行授權(quán),除了在程序中去遍歷所有的權(quán)限規(guī)則,我目前是沒有想到有其它別的好的辦法可以獲得某個(gè)人所具有的所有功能,如果有人有好的辦法請告知。),去遍歷權(quán)限表一個(gè)一個(gè)地去驗(yàn)證這個(gè)用戶(或角色)是否具有這個(gè)權(quán)限,而不得不去循環(huán)訪問數(shù)據(jù)庫。比如有100個(gè)權(quán)限,我就要訪問100次數(shù)據(jù)庫,我想這對每個(gè)人來說都是不可接受的,也是我對這個(gè)Provider進(jìn)行修改的主要原因。修改的目的就是要給它加上緩存權(quán)限的功能,要把數(shù)據(jù)庫中規(guī)則表的所有記錄都讀取下來,緩存在本地。這樣以后進(jìn)行授權(quán)驗(yàn)證的時(shí)候就不用擔(dān)心頻繁訪問數(shù)據(jù)庫了。緩存?緩存在內(nèi)存中合適嗎?Enterprise Library 也有提供緩存程序塊(Caching Application Block ),可以提供多種不同的緩存方式,可以緩存在內(nèi)存,文件和本地?cái)?shù)據(jù)庫中。經(jīng)過衡量,決定緩存在文件中。OK,打開DBRuleAuthorizationProvider源碼......
??? 找到DBRulesAuthorizationProviderData.cs,我不知道它叫什么名字,反正在這一整個(gè)企業(yè)庫里面每一個(gè)的配置節(jié)都有這樣的一個(gè)叫ProviderData的類。在里面添加上一個(gè)屬性的一個(gè)構(gòu)造函數(shù)。
//使用的緩存管理器的名稱
[XmlAttribute(AttributeName?=?"cacheManager")]
????????public?string?CacheManager
????????{
????????????get?{return?this.cacheManager;}
????????????set?{this.cacheManager????=?value;}
????????}
public?DbRulesAuthorizationProviderData(string?name,string?database,string?cacheManager)?:?this(name,database)
????????{
????????????this.cacheManager????=?cacheManager;
????????}
??? 修改DBRulesAuthorizationProviderNode.cs,修改這個(gè)是為了讓我們使用Configuration Console的時(shí)候可以為它指定一個(gè)緩存管理器。如下圖
在里面添加如下代碼 private?CacheManagerNode?cacheManager;
????????private?ConfigurationNodeChangedEventHandler?onCacheManagerRemoved;
????????private?ConfigurationNodeChangedEventHandler?onCacheManagerRenamed;
[Editor(typeof(ReferenceEditor),?typeof(UITypeEditor))]
????????[ReferenceType(typeof(CacheManagerNode))]
????????[Required]
????????[Description("The?database?instance?that?will?be?used?to?query?for?rules")]
????????public?CacheManagerNode?CacheManager
????????{
????????????get?{?return?this.cacheManager;?}
????????????set
????????????{
????????????????ILinkNodeService?service?=?GetService(typeof(ILinkNodeService))?as?ILinkNodeService;
????????????????Debug.Assert(service?!=?null,?"Could?not?get?the?ILinkNodeService");
????????????????this.cacheManager?=?(CacheManagerNode)service.CreateReference(cacheManager,?value,?onCacheManagerRemoved,?onCacheManagerRenamed);
????????????????this.DbRulesAuthorizationProviderData.CacheManager?=?string.Empty;
????????????????if?(this.cacheManager?!=?null)
????????????????{
????????????????????this.DbRulesAuthorizationProviderData.CacheManager?=?this.cacheManager.Name;
????????????????}
????????????}
????????}
private?void?OnCacheManagerRemoved(object?sender,ConfigurationNodeChangedEventArgs?args)
????????{
????????????this.cacheManager????=?null;
????????}
????????private?void?OnCacheManagerRenamed(object?sender,ConfigurationNodeChangedEventArgs?args)
????????{
????????????this.DbRulesAuthorizationProviderData.CacheManager????=?args.Node.Name;
????????}
//?
????????//??extended?by?hjf
????????//?
????????private?void?CreateCachingSettingsNode()
????????{
????????????if(!CachingSettingNodeExistes())
????????????{
????????????????AddConfigurationSectionCommand?cmd????=?new?AddConfigurationSectionCommand(Site,typeof(CacheManagerSettingsNode),CacheManagerSettings.SectionName);
????????????????cmd.Execute(Hierarchy.RootNode);
????????????}
????????}
????????private?bool?CachingSettingNodeExistes()
????????{
????????????CacheManagerSettingsNode????node????=?Hierarchy.FindNodeByType(typeof(CacheManagerSettingsNode))?as?CacheManagerSettingsNode;
????????????return?(node?!=?null);
????????}
修改構(gòu)造函數(shù)加上
this.onCacheManagerRemoved????=?new?ConfigurationNodeChangedEventHandler(this.onCacheManagerRemoved);
????????????this.onCacheManagerRenamed????=?new?ConfigurationNodeChangedEventHandler(this.onCacheManagerRenamed); 修改ResolveNodeReferences函數(shù)加上
CacheManagerSettingsNode?cacheManagerSettingNode????=?Hierarchy.FindNodeByType(typeof(CacheManagerSettingsNode))?as?CacheManagerSettingsNode;
????????????Debug.Assert(cacheManagerSettingNode?!=?null,"How?is?it?that?the?cachemanager?settings?are?not?there?");
????????????CacheManagerCollectionNode?cacheManagerCollectionNode????=?Hierarchy.FindNodeByType(typeof(CacheManagerCollectionNode))?as?CacheManagerCollectionNode;
????????????this.cacheManager????=?Hierarchy.FindNodeByName(cacheManager,this.DbRulesAuthorizationProviderData.CacheManager)?as?CacheManagerNode; 修改AddDefaultChildNodes()函數(shù),加上
CreateCachingSettingsNode(); OK,就這樣,把編譯好的DLL拷到C:\Program Files\Microsoft Enterprise Library\bin,再添加 Database Authorization Provider,配置項(xiàng),就加了一個(gè)CacheManager的值項(xiàng)了.
??? 現(xiàn)在我們看看DbRulesManager.cs,讀數(shù)據(jù)庫數(shù)據(jù)的操作都在這里了,現(xiàn)在CacheManager就用在這邊了。用了緩存后,我是將數(shù)據(jù)庫中所有的規(guī)則權(quán)限都一次性讀到本地中,用CacheManager緩存起來。原來還以為自己要寫存儲(chǔ)過程,仔細(xì)看一下代碼,它已經(jīng)寫好了一個(gè)方法,public AuthorizationRuleDataCollection GetAllRulesAsCollection(){},讀出所有的Rule,存在AuthorizationRuleDataCollection 里。查看一下AuthorizationRuleDataCollection 的定義。太好了,它可以根據(jù)RuleName ,取出對應(yīng)的RuleData。那我只要把生成的AuthorizationRuleDataCollection 對象保存起來不就可以了,還有一個(gè)問題AuthorizationRuleData是不可序列化的,沒法緩存。改一下Security 的源碼就行了,給AuthorizationRuleData加上[Serializable]屬性。新增代碼 private?const?string?STR_CACHE_RULESCOLLECTION????=?"Cache:RulesCollection";//緩存KEY
private?Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager?cacheManager????=?null;
//增加構(gòu)造函數(shù),初始化cacheManager
public?DbRulesManager(string?databaseService,string?cacheManagerService,ConfigurationContext?config)?:?this(databaseService,config)
????????{
????????????CacheManagerFactory?factory????=?new?CacheManagerFactory(config);
????????????cacheManager????=?factory.GetCacheManager(cacheManagerService);
????????}
//增加Property,外面調(diào)用這個(gè)屬性就可以了
public?AuthorizationRuleDataCollection?AllRuleCollection
????????{
????????????get
????????????{
????????????????AuthorizationRuleDataCollection?m_rulesCollection????=?null;
????????????????if(cacheManager[STR_CACHE_RULESCOLLECTION]?!=?null)
????????????????????m_rulesCollection????=?cacheManager[STR_CACHE_RULESCOLLECTION]?as?AuthorizationRuleDataCollection;
????????????????if(m_rulesCollection?==?null)
????????????????{
????????????????????m_rulesCollection????=?GetAllRulesAsCollection();
????????????????????AllRuleCollection????=?m_rulesCollection;
????????????????}
????????????????return?m_rulesCollection;
????????????}
????????????set
????????????{
????????????????if(value?==?null)
????????????????????cacheManager.Remove(STR_CACHE_RULESCOLLECTION);
????????????????else
????????????????????//
????????????????????//?緩存數(shù)據(jù)一天。
????????????????????//
????????????????????cacheManager.Add(STR_CACHE_RULESCOLLECTION,value,CacheItemPriority.High,null,new?SlidingTime(new?TimeSpan(1,0,0,0)));
????????????}
????????}
最后,我們來修改DBRulesAuthorizationProvider.cs,這個(gè)就是這個(gè)Provider對外提供的調(diào)用方法,我們只要修改根據(jù)RuleName讀出Expression的那段代碼就行了.
//增加字段
private?string?cacheManager;
//????????????????mgr?=?new?DbRulesManager(database,?this.securityConfigurationView.ConfigurationContext);
//用這個(gè)函數(shù)替換上面的函數(shù)
????????????mgr?=?new?DbRulesManager(database,cacheManager,this.securityConfigurationView.ConfigurationContext);
//增加下面的函數(shù)
private?BooleanExpression?GetParsedExpression(string?Expression)
????????{
????????????Parser?p????=?new?Parser();
????????????return?p.Parse(Expression);
????????}
//修改IConfigurationProvider的public?override?void?Initialize(ConfigurationView?configurationView)增加這句代碼
cacheManager????=?data.CacheManager;
整個(gè)的修改工作就這樣了,把編譯好的DLL Copy到Enterprise Library安裝目錄的bin目錄下,就可以使用了,有一點(diǎn)要注意,這期間我修改了Security 工程的AuthorizationRuleData類,請也將它重新編譯一下,Copy 到bin 目錄下,否則數(shù)據(jù)將無法緩存。還有一點(diǎn)就是如何控制緩存的過期,在修改權(quán)限表達(dá)式的時(shí)候可要記住清空緩存喔,我曾想在DbRulesAuthorizationProvider,增加一個(gè)方法設(shè)計(jì)緩存的過期,可是程序是通過IAuthorizationProvider接口來調(diào)用的,修改它就要修改很多地方了。而為了使用的一致性又不想運(yùn)行時(shí)去將它轉(zhuǎn)換成DbRulesAuthorizationProvider類型.....還在考慮中,呵呵
??? 第一次隨筆,組織得會(huì)比較亂,沒辦法,就這水平了,請見諒。
轉(zhuǎn)載于:https://www.cnblogs.com/hjf1223/archive/2005/08/11/212622.html
總結(jié)
以上是生活随笔為你收集整理的对DbRuleAuthorizationProvider的修改的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 找到一个不错的ASP.net电子图书下载
- 下一篇: File,FileInfo;Direct