愛上MVC~AuthorizeAttribute驗證不(bu)通過如(ru)何停止當前上下文
我們知道mvc里有一些過(guo)(guo)濾(lv)器(qi),AuthorizeAttribute用(yong)來(lai)做授(shou)權,一般(ban)在用(yong)戶(hu)授(shou)權方面可(ke)(ke)以使(shi)用(yong)它(ta),當(dang)使(shi)用(yong)沒有登陸(lu),我們直接跳(tiao)到登陸(lu)頁,這(zhe)是沒有問題的(de),可(ke)(ke)我要(yao)說的(de)是,當(dang)用(yong)戶(hu)對某個Action沒有權限時,如何禁止(zhi)對當(dang)前action的(de)執行(xing),這(zhe)個聽起(qi)來(lai)很不(bu)(bu)可(ke)(ke)思議,因為我們一般(ban)感覺,當(dang)AuthorizeAttribute驗(yan)證不(bu)(bu)通(tong)過(guo)(guo)后,它(ta)的(de)當(dang)前action也不(bu)(bu)會被執行(xing),可(ke)(ke)事實并非(fei)如此!
看下面代碼
public override void OnAuthorization(AuthorizationContext filterContext) { #region 例外 bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true) || filterContext.RequestContext.HttpContext.Request.Url.Host == "localhost"; if (skipAuthorization) return; #endregion //當前為正常頁(ye)面,不是分布視圖 var isValid = false; //當前用戶的菜單和權限 var menuAuthority = Lind.DDD.Utils.SerializeMemoryHelper.DeserializeFromJson<List<Tuple<int, string, int>>>(CurrentUser.ExtInfo); //當前(qian)控制器對應的(de)權限值 var controllerName = filterContext.RouteData.Values["controller"].ToString(); var actionName = filterContext.RouteData.Values["action"].ToString(); //當前權限(xian),先找完全匹配的,如果沒有(you),再找controller匹配的 var current = menuAuthority.Find(i => !string.IsNullOrWhiteSpace(i.Item2) && i.Item2.ToLower() == ("/" + controllerName + "/" + actionName).ToLower()); if (current != null) { if ((current.Item3 & (int)Authority) == (int)Authority) { isValid = true; } } if (!isValid) { string returnUrl = filterContext.RequestContext.HttpContext.Request.UrlReferrer == null ? "/AdminCommon/LogOn" : filterContext.RequestContext.HttpContext.Request.UrlReferrer.AbsolutePath; filterContext.RequestContext.HttpContext.Response.Write("<div style='text-align:center'><div style='MARGIN-RIGHT: auto;MARGIN-LEFT: auto;width:300px;min-height:150px;border: 2px dashed #aaa;color: red; font-size: 14px;padding: 5px;text-align: center;vertical-align:middle;'><h2>警告</h2><p>您沒有被(bei)授權此操作,請<a href=" + returnUrl + ">單擊返回</a></p><p style='color:#000'>時間:" + DateTime.Now + "</p></div></div>"); filterContext.RequestContext.HttpContext.Response.End(); filterContext.Result = new EmptyResult();//清空當前Action,不執(zhi)行當前Action代碼 } }
上(shang)面(mian)代(dai)碼(ma)是大叔在進行權(quan)限設計(ji)時用到(dao)的(de),請注(zhu)意最(zui)后一句EmptyResult,這(zhe)個(ge)方法表示返回一個(ge)空(kong)(kong)的(de)Actioin的(de)結果,只(zhi)有(you)加上(shang)這(zhe)個(ge)空(kong)(kong)結果,你(ni)的(de)當前Action才(cai)不會被執行,大叔覺得,這(zhe)是一種架構設計(ji)的(de)新思(si)想(xiang),像沒多架構都使用了(le)這(zhe)種空(kong)(kong)對(dui)象(xiang)的(de)技術,空(kong)(kong)對(dui)象(xiang)即什么事件都不做(zuo),但它并不是null!
// 摘要: // 表示一個不執行(xing)任何操作(zuo)的結果(guo),如不返回任何內容的控制器操作(zuo)方法。 public class EmptyResult : ActionResult { // 摘要: // 初(chu)始化 System.Web.Mvc.EmptyResult 類(lei)的新實例。 public EmptyResult(); // 摘要: // 執行(xing)指定的結果上(shang)下文。 // // 參數: // context: // 結果上(shang)下文。 public override void ExecuteResult(ControllerContext context); }
感覺各位(wei)對大叔的支持!