国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

重寫Authorize過濾器導致的登錄已經失效,但卻沒有跳轉到登錄頁問題的解決

2019-11-09 20:22:34
字體:
來源:轉載
供稿:網友

最近在調試一個新做的MVC項目的時候發現在類別添加頁面大類列表為空,檢查發現并沒有從數據庫中讀取到類別數據。很納悶,由于這個類別列表是Ajax請求所得,審查元素,檢查相應的js文件。發覺有錯誤提示:

ReferenceError: loginVM is not defined

檢查loginVM,發覺是登錄模塊,這才發現登錄已經超時。這什么情況,登錄超時不是應該自動跳轉到登錄頁面么。沒執行?由于我這個后臺控制登錄權限驗證的是Authorize過濾器,于是進行相應檢查。

我寫的是AdminUnauthorizedReturnUrl類,繼承的是xmlAuthorizeAttribute類,代碼如下:

public class AdminUnauthorizedReturnUrl : XMLAuthorizeAttribute    {         PRotected override bool AuthorizeCore(HttpContextBase httpContext)        {            EventLog.WriteLog("child AuthorizeCore");            bool hasRole = base.AuthorizeCore(httpContext);             //如果為空,則表示尚未登錄,為false            if (httpContext == null)            {                throw new ArgumentNullException("httpContext");            }             return hasRole;        }         public override void OnAuthorization(AuthorizationContext filterContext)        {            EventLog.WriteLog("child OnAuthorization");            if (filterContext.HttpContext.User == null)            {                return;            }            if (filterContext.HttpContext.User.Identity == null)            {                return;            }            string userId = filterContext.HttpContext.User.Identity.GetUserId();            EventLog.WriteLog("kong:" + userId.IsNullOrEmpty());            if (userId.IsNullOrEmpty())            {                //EventLog.WriteLog("為空");                return;            }            using (var db = new LMIdentityDbContext())            {                var user = db.Users.Find(userId);                if (user == null)                {                    //EventLog.WriteLog("為空1");                    return;                }                string role = user.Role;                //EventLog.WriteLog("role:" + role); ;                //EventLog.WriteLog(user.UserName);                 //表示是管理員,且用戶已經被驗證                if (filterContext.HttpContext.User.Identity.IsAuthenticated && role == "admin")                {                     bool hasRole = (this.Roles == null || this.Roles.Length == 0 ||                                   this.Roles.Any((string a) => filterContext.HttpContext.User.IsInRole(a)));                    //EventLog.WriteLog("" + (hasRole));                     if (!hasRole)   //表示沒有后臺操作的角色權限                    {                        //表示沒有頁面的操作權限,則跳到平臺后臺首頁                        filterContext.Result = new RedirectResult("/admin/home/UnAuthorize", true);                        return;                    }                 }             }              base.OnAuthorization(filterContext);         }           /// <summary>        /// 權限跳轉類        /// </summary>        /// <param name="filterContext"></param>        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)        {             base.HandleUnauthorizedRequest(filterContext);          }      }
XMLAuthorizeAttribute類的代碼如下:
 public class XMLAuthorizeAttribute : AuthorizeAttribute    {        public new string[] Roles        {            get;            set;        }         protected override bool AuthorizeCore(HttpContextBase httpContext)        {            EventLog.WriteLog("base AuthorizeCore");            if (httpContext == null)            {                throw new ArgumentNullException("HttpContext");            }             return httpContext.User.Identity.IsAuthenticated && (this.Roles == null || this.Roles.Length == 0 || this.Roles.Any((string a) => httpContext.User.IsInRole(a)));        }         public override void OnAuthorization(AuthorizationContext filterContext)        {            EventLog.WriteLog("base OnAuthorization");            string text = (filterContext.RouteData.DataTokens["area"] as string) ?? "";            string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;            string actionName = filterContext.ActionDescriptor.ActionName;            //獲取頁面的所有權限,頁面權限形式:admin,審核,財務,agent,短信            string actionRoles = GetRoles.GetActionRoles(actionName, ((text.Length > 0) ? (text + "/") : "") + controllerName);            //EventLog.WriteLog(controllerName);            //EventLog.WriteLog(actionName);            //EventLog.WriteLog("actionRoles" + (actionRoles));            this.Roles = actionRoles.Split(new string[]			{				","			}, StringSplitOptions.RemoveEmptyEntries);             base.OnAuthorization(filterContext);        }         protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)        {            base.HandleUnauthorizedRequest(filterContext);            //if (filterContext.HttpContext.Response.StatusCode == 401)            //{            //    filterContext.Result = new RedirectResult("/");            //}        }     }
  我們知道權限過濾器的執行順序為:OnAuthorization-->AuthorizeCore-->HandleUnauthorizedRequest ,因此我在AdminUnauthorizedReturnUrl類
中的AuthorizeCore及OnAuthorization增加了中間變量輸出輸出。使用的是eventlog.writelog輸出。編譯刷新當前頁面后輸出如下:
child OnAuthorization
kong:True
這使我確定了在子類的OnAuthorization中由于userid為空,執行了return.但并沒有自動跳轉到AuthorizeCore中去判斷hasRole是否為真。剛開始是以為
后臺頁面權限的xml文件沒配置完全造成。配置后,結果仍是如此。進行各種嘗試,均沒有解決。后來想到,難道要調整base.OnAuthorization(filterContext);
的位置,因為我是把他放置到方法結尾了。于是我把其調整到方法開始的第一行,這次沒有再停留到原頁面,直接跳轉到了登錄頁面。看來真是這里的問題,
之所以剛開始沒考慮到是這里的問題,是因為以前方法重寫的時候,base執行父類方法的語句,放在開始和結尾是沒分別的。為什么在這個方法中
就出問題了呢。于是我反編譯了system.web.mvc中的AuthorizeAttribute類。找到了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 flag = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true);            if (flag)            {                return;            }            if (this.AuthorizeCore(filterContext.HttpContext))            {                HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;                cache.SetProxyMaxAge(new TimeSpan(0L));                cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null);                return;            }            this.HandleUnauthorizedRequest(filterContext);        }
這里看到了這行語句:
if (this.AuthorizeCore(filterContext.HttpContext)),看到這行語句我也理解了為什么執行順序是OnAutorization=>AutorizeCore,原來在這個
OnAuthorization方法中調用了AuthorizeCore方法。當AuthorizeCore返回false的時候執行了this.HandleUnauthorizedRequest(filterContext),
這個就是沒有權限要跳轉頁面的設置方法。
來看AuthorizeAttribute類中這個方法的源碼
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)        {            filterContext.Result = new HttpUnauthorizedResult();        }
執行的是這行代碼:
filterContext.Result = new HttpUnauthorizedResult();
而我在重寫的AdminUnauthorizedReturnUrl類及XMLAuthorizeAttribute類中均沒有做跳轉頁面的改變。因此系統默認還是執行的
filterContext.Result = new HttpUnauthorizedResult();這個方法執行的是項目中Startup類中設置的默認跳轉頁面。我這里設置的是
/account/login。到這里對權限過濾器的執行有了深入的理解,也明白了為什么base.OnAuthorization(filterContext);必須放置在OnAuthorization
方法的開始。問題也得以解決


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 金沙县| 始兴县| 武陟县| 丹巴县| 白朗县| 呼图壁县| 商都县| 邵东县| 桂东县| 宜兰市| 苏尼特左旗| 涿州市| 商都县| 海丰县| 广宁县| 襄城县| 新昌县| 萝北县| 贵港市| 故城县| 饶河县| 广饶县| 米脂县| 晋城| 长治县| 托里县| 卢龙县| 临江市| 乐昌市| 连云港市| 云梦县| 凌云县| 靖州| 和平县| 永和县| 闽侯县| 忻城县| 上犹县| 鲁山县| 丰城市| 当涂县|