好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

利用EntLib授权机制实现对ASP.NET页面的自动授权

利用EntLib授权机制实现对ASP.NET页面的自动授权

ASP.NET默认采用 UrlAuthorizationModule 和 FileAuthorizationModule 分别实现针对请求地址和物理文件的授权,但是在很多情况下我们需要额外的授权方式。Entlib提供了一种基于表达式的授权方式,它允许我们以一个表达式的方式来定义授权的规则。在新的项目中我们希望利用EntLib的授权框架来实现针对ASP.NET页面的自动授权,本文描述的解决方案是我刚刚想到的,希望广大网友朋友们帮助评估一下。[源代码从 这里 下载]

目录 
一、实例演示 
二、AuthorizationFilterAttribute 
三、AuthorizeAttribute 
四、PageBase

一、实例演示

我们先来作一个简单的实例演示。如下所示的EntLib安全模块的配置,如果读者对此不了解也没有关系,在这里我们只需要关注定义其中的一个授权规则(Authorization Rule):“ I:Foo OR R:Admin ”。这是一个逻辑表达式,前缀I:和R:分别表示用户名(Identity)和角色(Role),整个表达式表示的授权逻辑是:“帐号为Foo的用户和所有具有Admin角色的用户”有权限方法与此表达式关联的操作或者资源。配置还定义了该授权规则的名称“ FooOrAdmin ”。

    1:   <  configuration  > 
    2:     <  configSections  > 
    3:       <  section   name  ="securityConfiguration"  
    4:                type  ="Microsoft.Practices.EnterpriseLibrary.Security.Configuration.SecuritySettings,  
    5:                     Microsoft.Practices.EnterpriseLibrary.Security" /> 
    6:     </  configSections  > 
    7:     <  securityConfiguration   defaultAuthorizationInstance  ="Authorization Rule Provider"  > 
    8:       <  authorizationProviders  > 
    9:         <  add   name  ="Authorization Rule Provider" 
   10:              type  ="Microsoft.Practices.EnterpriseLibrary.Security.AuthorizationRuleProvider,  
   11:                   Microsoft.Practices.EnterpriseLibrary.Security" > 
   12:           <  rules  > 
   13:             <  add   expression  ="I:Foo OR R:Admin"   name  ="FooOrAdmin"   /> 
   14:           </  rules  > 
   15:         </  add  > 
   16:       </  authorizationProviders  > 
   17:     </  securityConfiguration  > 
   18:   </  configuration  > 

我们添加一个需要授权的Web页面(Default.aspx),并且使用上面定义的表达式来作为该页面的授权规则,我们通过自定义的AuthorizeAttribute特性实现两者之间的关联(该特性构造函数中指定的字符串正是配置的授权规则名称)。除此之外,Web页面对应的类型继承自我们自定义的基类PageBase。

    1:   [Authorize(  "FooOrAdmin"  )] 
    2:   public   partial   class  Default :  PageBase 
    3:  {   
    4:  }

我们随后添加一个登录页面,具体的实现就不再这里一一介绍了。为了模拟不同的登录用户具有不同的权限,我们通过注册HttpApplication的AuthenticateRequest事件来对当前Principal进行定制。具体的定义如下所示:如果用户名为Bar,我们让当前的Principal具有Admin角色,对于其他帐号的登录用户,角色列表为空。

    1:   public   class  Global : System.Web.HttpApplication
    2:  {
    3:       protected   void  Application_AuthenticateRequest( object  sender, EventArgs e)
    4:      {
    5:           if  ( null  == HttpContext.Current.User || !HttpContext.Current.User.Identity.IsAuthenticated)
    6:          {
    7:               return ;
    8:          }
    9:   
   10:          IIdentity identity =  new  GenericIdentity(HttpContext.Current.User.Identity.Name);
   11:           string [] roles =  null ;
   12:           if  (identity.Name.ToLower() ==  "bar" )
   13:          {
   14:              roles =  new   string [] {  " Admin "  };
   15:          }
   16:          HttpContext.Current.User =  new  GenericPrincipal(identity, roles);
   17:      }
   18:  }

由于页面Default.aspx与配置名称为FooOrAdmin的授权规则进行了关联,根绝授权规则表达式定义和针对不同用户的角色列表,意味着当我们以账户Foo和Bar登录后才能访问该页面,“自动化授权”可以通过下图得到证实:当前用户为Foo和Bar时,页面得以正常显示;而当我们以Baz的身份登录后,显示“Access denied…”。

二、AuthorizationFilterAttribute

这里我吸取了ASP.NET MVC基于AuthorizationFilter的授权方式,不同的是AuthorizationFilter在ASP.NET MVC中以特性的方式应用到Controller类型和Action方法上,这里我们则将它应用到Web页面对应的类上。AuthorizationFilterAttribute作为授权筛选器特性的基类定义如下,由于多个特性可以同时应用到同一个类型上,它们的执行顺序通过属性Order来控制。具体的授权判断以及对非授权请求的处理定义在方法OnAuthorization方法上。

    1:  [AttributeUsage( AttributeTargets.Class, AllowMultiple =  true )]
    2:   public   abstract   class  AuthorizationFilterAttribute:Attribute
    3:  {
    4:       public   int  Order { get; set; }
    5:       public   abstract   bool  OnAuthorization(AuthorizationContext context);        
    6:  }
    7:   
    8:   public   class  AuthorizationContext
    9:  {
   10:       public  HttpContext  HttpContext { get;  private  set; }
   11:       public   bool          UnAuthorizedRequestHandled { get; set; }
   12:   
   13:       public  AuthorizationContext(HttpContext httpContext)
   14:      {
   15:           this .HttpContext = httpContext;
   16:      }
   17:  }

OnAuthorization方法返回值代表的是真否授权的判断,它具有一个类型为AuthorizationContext参数。AuthorizationContext是对HttpContext对象的封装,属性UnAuthorizedRequestHandled 表示是否完成了针对非授权请求的处理。如果多个AuthorizationFilterAttribute应用到同一个类型上,如果前面执行的AuthorizationFilterAttribute将传入的AuthorizationContext的这个属性设置为True,后续的将不在执行。

三、AuthorizeAttribute

基于EntLib的授权通过AuthorizeAttribute来实现。如下面的代码片断所示,AuthorizeAttribute 直接继承自AuthorizationFilterAttribute,代表授权规则配置名称的属性AuthorizationRule 在构造函数中被初始化。在实现的OnAuthorization我们按照Entlib授权框架的编程模式判断当前Principal是否具有针对指定授权规则的权限,对于非授权请求我们直接调用HandleUnauthorizedRequest方法进行处理。具体的处理逻辑很简单:直接相应一段文字“Access denied…”(正是上面截图中显示的文字)。出于可扩展的考虑,我们将此方法定义成受保护的虚方法。

    1:  [AttributeUsage( AttributeTargets.Class, AllowMultiple =  true )]
    2:   public   class  AuthorizeAttribute : AuthorizationFilterAttribute
    3:  {
    4:       public   string  AuthorizationRule { get;  private  set; }
    5:       public  AuthorizeAttribute( string  authorizationRule)
    6:      {
    7:          Guard.ArgumentNotNullOrEmpty(authorizationRule,  "authorizationRule" );
    8:           this .AuthorizationRule = authorizationRule;
    9:      }
   10:   
   11:       public   override   bool  OnAuthorization(AuthorizationContext context)
   12:      {
   13:          IAuthorizationProvider authorizationProvider = AuthorizationFactory.GetAuthorizationProvider();
   14:           if  (authorizationProvider.Authorize(context.HttpContext.User,  this .AuthorizationRule))
   15:          {
   16:               return   true ;
   17:          }
   18:           this .HandleUnauthorizedRequest(context);
   19:           return   false ;
   20:      }
   21:   
   22:       protected   virtual   void  HandleUnauthorizedRequest(AuthorizationContext context)
   23:      {
   24:          context.HttpContext.Response.Write(context.HttpContext.User.Identity.Name +  ": Access denied..." );
   25:      }
   26:  }


四、PageBase

我们知道针对一个ASP.NET 资源的请求最后大都通过一个对应的HttpHandler来处理,这个授权解决方案的基本思路就是通过自定义HttpHandler实现自动化授权检验。Page类型是我们最为熟悉的HttpHandler,为此我们定义了如下一个继承自它的类型PageBase。如下面的代码片断所示,在重写的ProcessRequest方法中实现了对应用在当前类型上的AuthorizationFilterAttribute特性的解析和执行,进而提供了对授权的实现。

    1:   public   abstract   class  PageBase: Page
    2:  {
    3:       public   override   void  ProcessRequest(HttpContext context)
    4:      {
    5:          var filterAttributes =  this .GetType().GetCustomAttributes( true )
    6:                                  .OfType<AuthorizationFilterAttribute>()
    7:                                  .OrderBy(attribute => attribute.Order);
    8:          AuthorizationContext authorizationContext =  new  AuthorizationContext(context);
    9:           bool  isAuthorized =  true ;
   10:           foreach  (AuthorizationFilterAttribute attribute  in  filterAttributes)
   11:          {
   12:              isAuthorized = attribute.OnAuthorization(authorizationContext);
   13:               if  (authorizationContext.UnAuthorizedRequestHandled)
   14:              {
   15:                   break ;
   16:              }
   17:          }
   18:   
   19:           if  (isAuthorized)
   20:          {
   21:               base .ProcessRequest(context);
   22:          }
   23:      }    
   24:  }

作者: Artech
出处: http://artech.cnblogs测试数据/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类:  [02] 编程技巧 ,  [14] 框架设计

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于利用EntLib授权机制实现对ASP.NET页面的自动授权的详细内容...

  阅读:38次

上一篇: EasyNet.Solr架构

下一篇:SQL不知道的事