程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> 認識ASP.NET MVC的5種AuthorizationFilter

認識ASP.NET MVC的5種AuthorizationFilter

編輯:關於ASP.NET

在總體介紹了篩選器及其提供機制(《深入探討ASP.NET MVC的篩選器》)之後,我們按照執行的先後順序對四種不同的篩選器進行單獨介紹,首先來介紹最先執行的AuthorizationFilter。從命名來看,AuthorizationFilter用於完成授權相關的工作,所以它應該在Action方法被調用之前執行才能起到授權的作用。不僅限於授權,如果我們希望目標Action方法被調用之前中斷執行的流程“做點什麼”,都可以以AuthorizationFilter的形式來實現。

一、IAuthorizationFilter

所有的AuthorizationFilter實現了接口IAuthorizationFilter。如下面的代碼片斷所示,IAuthorizationFilter定義了一個OnAuthorization方法用於實現授權的操作。作為該方法的參數filterContext是一個表示授權上下文的AuthorizationContext對象, 而AuthorizationContext直接繼承自ControllerContext。

   1: public interface IAuthorizationFilter
2: {
3: void OnAuthorization(AuthorizationContext filterContext);
4: }
5:
6: public class AuthorizationContext : ControllerContext
7: {
8: public AuthorizationContext();
9: public AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor);
10:
11: public virtual ActionDescriptor ActionDescriptor { get; set; }
12: public ActionResult Result { get; set; }
13: }

AuthorizationContext的ActionDescriptor屬性表示描述當前執行Action的ActionDescriptor對象,而Result屬性返回一個用於在授權階段呈現的ActionResult。AuthorizationFilter的執行是ActionInvoker進行Action執行的第一項工作,因為後續的工作(Model綁定、Model驗證、Action方法執行等)只有在成功授權的基礎上才會有意義。

ActionInvoker在通過執行AuthorizationFilter之前,會先根據當前的Controller上下文和解析出來的用於描述當前Action的ActionDescriptor,並以此創建一個表示授權上下文的AuthorizationContext對象。然後將此AuthorizationContext對象作為參數,按照Filter對象Order和Scope屬性決定的順序執行所有AuthorizationFilter的OnAuthorization。

在所有的AuthorizationFilter都執行完畢之後,如果指定的AuthorizationContext對象的Result屬性表示得ActionResult不為Null,整個Action的執行將會終止,而ActionInvoker將會直接執行該ActionResult。一般來說,某個AuthorizationFilter在對當前請求實施授權的時候,如果授權失敗它可以通過設置傳入的AuthorizationContext對象的Result屬性響應一個“401,Unauthrized”回復,或者呈現一個錯誤頁面。

二、AuthorizeAttribute

如果我們要求某個Action只能被認證的用戶訪問,可以在Controller類型或者Action方法上應用具有如下定義的AuthorizeAttribute特性。AuthorizeAttribute還可以具體限制目標Action可被訪問的用戶或者角色,它的Users和Roles屬性用於指定被授權的用戶名和角色列表,中間用采用逗號作為分隔符。如果沒有顯式地對Users和Roles屬性進行設置,AuthorizeAttribute在進行授權操作的時候只要求訪問者是被認證的用戶。

   1: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited=true, AllowMultiple=true)]
2: public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
3: {
4: //其他成員
5: public virtual void OnAuthorization(AuthorizationContext filterContext);
6: protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);
7:
8: public string Roles { get; set; }
9: public override object TypeId { get; }
10: public string Users { get; set; }
11: }

如果授權失敗(當前訪問者是未被授權用戶,或者當前用戶的用戶名或者角色沒有在指定的授權用戶或者角色列表中),AuthorizeAttribute會創建一個HttpUnauthorizedResult對象,並賦值給AuthorizationContext的Result屬性,意味著會響應一個狀態為“401,Unauthorized”的回復。如果采用Forms認證,配置的登錄頁面會自動被顯示。

很多會將AuthorizeAttribute對方法的授權與PrincipalPermissionAttribute等同起來,實際上不但它們實現授權的機制不一樣(後者是通過代碼訪問安全檢驗實現對方法調用的授權),它們的授權策略也一樣。以下面定義的兩個方法為例,應用了PrincipalPermissionAttribute的FooOrAdmin意味著可以被帳號為Foo或者具有Admin角色的用戶訪問,而應用了AuthorizeAttribute特性的方法FooAndAdmin方法則只能被用戶Foo訪問,而且該用戶必須具有Admin角色。也就是說PrincipalPermissionAttribute特性對User和Role的授權邏輯是“邏輯或”,而AuthorizeAttribute 采用的則是“邏輯與”。

   1: [PrincipalPermission( SecurityAction.Demand,Name="Foo", Role="Admin")]
2: public void FooOrAdmin()
3: { }
4:
5: [Authorize(Users="Foo", Roles="Admin")]
6: public void FooAndAdmin()
7: { }

除此之外,我們可以將多個PrincipalPermissionAttribute和AuthorizeAttribute應用到同一個類型或者方法上。對於前者,如果當前用於通過了任意一個PrincipalPermissionAttribute特性的授權就有權調用目標方法;對於後者來說,意味著需要通過所有AuthorizeAttribute特性的授權在具有了調用目標方法的權限。以如下兩個方法為例,用戶Foo或者Bar可以有權限調用FooOrBar方法,但是沒有任何一個用戶有權調用CannotCall方法(因為一個用戶只一個用戶名)。

   1: [PrincipalPermission( SecurityAction.Demand, Name="Foo")
2: [PrincipalPermission( SecurityAction.Demand, Name="Bar")]
3: public void FooOrBar()
4: { }
5:
6: [Authorize(Users="Foo")]
7: [Authorize(Users="Bar")]
8: public void CannotCall()
9: {}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved