Community Server专题十:MemberRole之RoleManager

 

Community Server专题十:MemberRoleRoleManager<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

由于最近忙于一些琐事,近半个月都没有写新的专题,今天忙里抽闲赶紧补上,实在是抱歉。

 

设计做多了就会发现,用户权限管理是一个永恒的话题,几乎没有什么项目不需要权限和角色管理的,可能会无数次去写角色管理的代码,而且会根据项目的不同粒度也会有所不同。在CS中,采用了MemberRole.dll中的RoleManager进行角色管理,该角色管理机制同样在asp.net 2.0 beta2 中得到应用。在分析代码之前先看看数据库中的角色的关系表:<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />%7BBC4F47EB-7014-4F8A-855F-484A7F6CD166%7D0.jpg

表分两种前缀,一种是“aspnet_”另一种是“cs_”,“aspnet_”是采用MemberRole.dll组件所必需的一些表,包括过程和视图等都是这样命名的,在asp.net 2.0 beta2 中你也可以看到同样的表、视图与储存过程。“cs_”前缀是CS系统需要的表,由此可以看到MemberRole.dll中的RoleManager只管理到角色级别,通常我们还会给角色添加一些权限,然后在应用系统中判断角色拥有的权限从而决定用户是否有访问的权限,当然一个用户可以有多个角色,一个角色又可以有多个权限。有时你设计的某些系统是不需要做如此多权限管理的,只要多个角色就可以解决问题,那么就不再需要扩展数据库,直接使用MemberRole.dll中的RoleManager就可以了。

注意:你可能会对cs_SectionPermissionscs_ProductPermissions表产生疑惑,这里有两个权限表,分别管理两种权限,cs_SectionPermissions中存储节点级别的权限,如Blog中,是否有权限开通blog,管理所有blog等,这些权限就放在cs_SectionPermissions,但是对于每个blog,如我的blog,现在不想要某个用户访问,或者需要某个用户帮忙管理,再或者某个地方某些用户可以访问,某些不行,这样的权限就放入cs_ProductPermissions中设置。

RoleManager是一个HttpModule,由此可以在web.config中看到如下的配置文件:

 

None.gif < add  name ="RoleManager"  type ="Microsoft.ScalableHosting.Security.RoleManagerModule, MemberRole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b7c773fb104e7562"   />

 

这也是RoleManager角色管理的入口点,同时,在RoleManager中实现了IConfigurationSectionHandler接口,用来读取Web.config中的以下配置:

        

None.gif < roleManager 
None.gif
None.gif              
cacheRolesInCookie ="true"  cookieName =".CSRoles"  cookieTimeout ="90"
None.gif
None.gif              cookiePath
="/"   cookieRequireSSL ="false"  cookieSlidingExpiration ="true"  
None.gif
None.gif              createPersistentCookie
="true"  cookieProtection ="All"  maxCachedResults ="1000"   >
None.gif
None.gif              
< providers >
None.gif
None.gif                   
< add
None.gif
None.gif                       
name ="CommunityServerSqlProvider"
None.gif
None.gif                       type
="CommunityServer.Components.CSRoleProvider, CommunityServer.Components"
None.gif
None.gif                       connectionStringName
="SiteSqlServer"
None.gif
None.gif                       applicationName
="dev"
None.gif
None.gif                       description
="Stores and retrieves roles data from the local Microsoft SQL Server database"  
None.gif
None.gif                   
/>
None.gif
None.gif              
</ providers >
None.gif
None.gif     
</ roleManager >      
None.gif
None.gif

再这里我们又看到了Provider模型,其实asp.net 2.0 beta2中大量使用了这种数据访问模型。它的优点我在前面的专题中已经讲解过,不理解的朋友可以看我之前的专题。

RoleManager很重要的一个类就是:

%7B366CB481-0CF3-449F-AB21-88B343AF1921%7D0.jpg该类继承至IPrincipal,因此我们可以在用户登录后通过检查当前ContextUser的一些方法和属性,判断拥护是否拥有某角色。操作的方法在RoleMangerModule类下的OnEnter下:

ContractedBlock.gif ExpandedBlockStart.gif OnEnter方法
None.gifprivate void OnEnter(object source, EventArgs eventArgs)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif      
if (Roles.Enabled)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif            HttpContext context1 
= ((HttpApplication) source).Context;
InBlock.gif            
if (context1.User == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                  context1.User 
= new GenericPrincipal(new GenericIdentity(string.Empty, string.Empty), new string[0]);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
if (this._eventHandler != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                  RoleManagerEventArgs args1 
= new RoleManagerEventArgs(context1);
InBlock.gif                  
this._eventHandler(this, args1);
InBlock.gif                  
if (args1.RolesPopulated)
ExpandedSubBlockStart.gifContractedSubBlock.gif                  
dot.gif{
InBlock.gif                        
return;
ExpandedSubBlockEnd.gif                  }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
if (Roles.CacheRolesInCookie)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                  
if (context1.User.Identity.IsAuthenticated && (!Roles.CookieRequireSSL || context1.Request.IsSecureConnection))
ExpandedSubBlockStart.gifContractedSubBlock.gif                  
dot.gif{
InBlock.gif                        
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                              HttpCookie cookie1 
= context1.Request.Cookies[Roles.CookieName];
InBlock.gif                              
if (cookie1 != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                              
dot.gif{
InBlock.gif                                    
string text1 = cookie1.Value;
InBlock.gif                                    
if ((text1 != null&& (text1.Length > 0x1000))
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
dot.gif{
InBlock.gif                                          Roles.DeleteCookie();
ExpandedSubBlockEnd.gif                                    }

InBlock.gif                                    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                                    
dot.gif{
InBlock.gif                                          
if (((Roles.CookiePath != null&& (Roles.CookiePath.Length > 0)) && (Roles.CookiePath != "/"))
ExpandedSubBlockStart.gifContractedSubBlock.gif                                          
dot.gif{
InBlock.gif                                                cookie1.Path 
= Roles.CookiePath;
ExpandedSubBlockEnd.gif                                          }

InBlock.gif                                          cookie1.Domain 
= Roles.Domain;
InBlock.gif                                          context1.User 
= new RolePrincipal(context1.User.Identity, text1);
ExpandedSubBlockEnd.gif                                    }

ExpandedSubBlockEnd.gif                              }

ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                  }

InBlock.gif                  
else if (context1.Request.Cookies[Roles.CookieName] != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                  
dot.gif{
InBlock.gif                        Roles.DeleteCookie();
ExpandedSubBlockEnd.gif                  }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
if (!(context1.User is RolePrincipal))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                  context1.User 
= new RolePrincipal(context1.User.Identity);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif      }

ExpandedBlockEnd.gif}

None.gif
None.gif

由于知识点比较简单, MSDN上也有相关的IPrincipalIdentity的介绍,我就不细细的分析。

RoleManger里,很多地方使用了Cookie,这样做提高了不少的效率,你想,如果每个用户每次访问一个页面都去读一次数据库,把该访问用户的权限读取出来,也许你聪明点,把该用户的权限先缓存在内存中,并且设置一定的过期时间,其实你还能再聪明一点,那就是把角色保存在客户端的Cookie,这样连服务器的内存都节约了。只有在用户第一次登录,或者清除了CookieCookie失效的情况下才需要访问数据库。但是这也带来一个问题,就是如果客户端禁止使用Cookie,用户将无法正常访问。CS中通过在web.config中可以配置是否启用这种机制。

 

到这里,整个MemberRole.dll算是粗略的讲解了一遍,由于时间上的限制不可能满足所有读者的要求,如果有疑问可以msn我或者给我留言。后面一些专题我将说说CS的页面,包括MasterPageThemeSkin等机制。

转载于:https://www.cnblogs.com/ugoer/archive/2005/10/10/251301.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值