AuthorizeAttribute是IAuthorizationFilter的默認實現,添加了Authorize特性的Action將對用戶進行驗證授權,只有通過了用戶才可以進入這個Action.
AuthorizeAttribute提供了四種操作方法,打開.net reflector查看源碼
1.在進入Action之前首先執行OnAuthorization
public virtual void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } if (OutputCacheAttribute.IsChildActionCacheActive(filterContext)) { throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache); } if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)) { if (this.AuthorizeCore(filterContext.HttpContext)) { HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache; cache.SetProxyMaxAge(new TimeSpan(0L)); cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null); } else { this.HandleUnauthorizedRequest(filterContext); } } }
2.在OnAuthorization內部會調用AuthorizeCore
protected virtual bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) { throw new ArgumentNullException("httpContext"); } IPrincipal user = httpContext.User; if (!user.Identity.IsAuthenticated) { return false; } if ((this._usersSplit.Length > 0) && !this._usersSplit.Contains<string>(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) { return false; } if ((this._rolesSplit.Length > 0) && !this._rolesSplit.Any<string>(new Func<string, bool>(user.IsInRole))) { return false; } return true; }
默認實現,不僅判斷是否授權,還可以具體到某一個角色,某一個用戶,但這些角色是哪裡來的呢?
(1)使用membership框架
(2)使用微軟最新的Identity框架
(3)自定義一個類繼承RoleProvider,並設置配置文件
<roleManager> <providers> <clear/> <add name="MyRoleProvider" type="Filter.Controllers.MyRoleProvider" /> </providers> </roleManager>
3.AuthorizeCore返回一個布爾值,表示是否通過授權,未通過將執行HandUnauthorizedRequest返回配置文件forms-loginUrl指向的頁面
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) { filterContext.Result = new HttpUnauthorizedResult(); }
4.OnAuthorization在緩存模塊請求授權時調用
protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext) { if (httpContext == null) { throw new ArgumentNullException("httpContext"); } if (!this.AuthorizeCore(httpContext)) { return HttpValidationStatus.IgnoreThisRequest; } return HttpValidationStatus.Valid; }
ActionFilterAttribute在mvc中沒有默認實現,需要自己定義
1.OnActionExecuting在OnAuthorization之後(實際上ActionFilter中的方法都在其之後)進入Action之前執行
2.OnActionExecuted在Action中所有語句都執行完之後執行
3.OnResultExecuting在執行操作結果(返回繼承自ActionResult的所有類型)前調用
4.OnResultExecuted在執行操作結果(返回繼承自ActionResult的所有類型)後調用
public class MyActionFilterAttribute : ActionFilterAttribute { /// <summary> /// 在執行操作方法之前由 ASP.NET MVC 框架調用。 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuting(ActionExecutingContext filterContext) { } /// <summary> /// 在執行操作方法後由 ASP.NET MVC 框架調用。 /// </summary> /// <param name="filterContext"></param> public override void OnActionExecuted(ActionExecutedContext filterContext) { } /// <summary> /// 在執行操作結果之前由 ASP.NET MVC 框架調用。 /// </summary> /// <param name="filterContext"></param> public override void OnResultExecuting(ResultExecutingContext filterContext) { } /// <summary> /// 在執行操作結果後由 ASP.NET MVC 框架調用。 /// </summary> /// <param name="filterContext"></param> public override void OnResultExecuted(ResultExecutedContext filterContext) { } }
HandleErrorAttribute是IException的默認實現,在調式的時候,出現異常就會蹦出那黃色的頁面
我們也可以自定義異常處理
需要注意的是ExceptionHandled表示這個異常是否已經處理(可能程序中有多個異常過濾器)
public class MyExceptionAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { if (!filterContext.ExceptionHandled)//避免重復處理 { //獲取拋出異常的對象 Exception ex = filterContext.Exception; //寫入異常日志 //已處理 filterContext.ExceptionHandled = false; } } }
IAuthenticationFilter是認證過濾器接口,他提供了兩個操作方法
1.OnAuthentication在所有過濾器執行前執行(包括授權過濾器)
2.OnAuthenticationChallenge在OnResultExecuting前執行
過濾器是把附加邏輯注入到MVC框架的請求處理.它們提供一種簡單而雅致的方式,實現了交叉關注,所謂交叉關注,是指可以用於整個應用程序,二用不適合放置在某個局部位置的功能,否則就會打破關注分離模式.典型的交叉關注例子就是登陸,授權以及緩存等.(摘自精通asp.net mvc5)