MVC源码学习之AuthorizeAttribute
常見的Controller定義方式:
public class HomeController : Controller {public ActionResult Index(){return View();} }如果對Action的操作需要權(quán)限管理的話,需要在Controller或者Action上面添加AuthorizeAttribute屬性或者AllowAnonymousAttribute屬性。
AllowAnonymousAttribute的意思很明確,允許匿名訪問。
AuthorizeAttribute類型有幾個屬性:Roles,Users,TypeId。
當(dāng)用戶請求一個Action時,會調(diào)用OnAuthorization方法。那么,我們來看看這個方法里面的代碼是什么:
public virtual void OnAuthorization(AuthorizationContext filterContext) {if (filterContext == null){throw new ArgumentNullException("filterContext");}if (OutputCacheAttribute.IsChildActionCacheActive(filterContext)){throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);}bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);if (skipAuthorization){return;}if (AuthorizeCore(filterContext.HttpContext)){HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;cachePolicy.SetProxyMaxAge(new TimeSpan(0));cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);}else{HandleUnauthorizedRequest(filterContext);} }中間有一段是判斷Action或者Controller是否被屬性AllowAnonymousAttribute描述,如果有,則返回。也就是說,無論Action或者是Controller哪一個上面被定義了[AllowAnonymous]屬性,那么,這個Action就會跳過驗證。
如果沒有的話,會判斷函數(shù)AuthorizeCore(filterContext.HttpContext)執(zhí)行的結(jié)果是否為true,這樣,我們進一步看函數(shù)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 (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)){return false;}if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)){return false;}return true; }邏輯比較清晰,如果用戶沒有登錄,返回false;如果授權(quán)用戶組長度大于0,但同時不包含當(dāng)前用戶,返回false;如果授權(quán)角色組長度大于0,但同時不包含當(dāng)前用戶所在的任何角色,返回false;符合前面所有的條件,則返回true。
到此,授權(quán)驗證的上下邏輯算是比較明了。
問題
實際操作中出現(xiàn)了疑惑:
如果在Controller那里定義了角色為"Users,Admin"的授權(quán),而在Action處定義其他角色的Authorize,會怎么樣呢?
測試思路,自定義一個CustomAuthorize,override上述兩個函數(shù)(這兩個函數(shù)都是virtual的),代碼復(fù)制微軟的源碼,加斷點調(diào)試。(重寫的代碼就不展示了。大部分復(fù)制,小部分微調(diào)下。),控制器代碼如下:
[CustomAuthorize(Roles="Users,Admin")] public class HomeController : Controller {public ActionResult Index(){return View();}[CustomAuthorize(Roles = "AAAAA")]public ActionResult About(){ViewBag.Message = "Your application description page.";return View();} }調(diào)試模式啟動Home下面的About頁面,在OnAuthorization里面加斷點,可以看到如下數(shù)據(jù):
1. 在filterContext.ActionDescriptor和filterContext.ActionDescriptor.ControllerDescriptor里面可以看到各自的Roles內(nèi)容
2. base.Roles的值為"Users,Admin"。
由此,我們可以得出:
當(dāng)Controller和Action都出現(xiàn)了角色授權(quán)時,多個授權(quán)不是合并,也不是取Action上面的,而是直接取Controller上面定義的角色,繼而判斷當(dāng)前用戶是否有授權(quán)。
?
Users是不是也是這樣的,有興趣的童鞋可以自己調(diào)試看看o(∩_∩)o ~
轉(zhuǎn)載于:https://www.cnblogs.com/icyJ/p/MVC_Authorize.html
總結(jié)
以上是生活随笔為你收集整理的MVC源码学习之AuthorizeAttribute的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ORA-16038: log 3 seq
- 下一篇: [SAP ABAP开发技术总结]ABAP