Lind.DDD.Authorization使用者授權介紹
阿新 • • 發佈:2018-12-29
Lind.DDD.Authorization是Lind.DDD框架的組成部分,之所以把它封裝到框架裡,原因就是它的通用性,幾乎在任何一個系統中,都少不了使用者授權功能,使用者授權對於任何一個系統來說都是必要的,像管理型的頁面都需要使用者先去登陸,然後拿到憑證,才可以進行訪問,這在MVC和WebApi體系結構裡是很容易實現的,像過濾器裡的AuthorizeAttribute和ActionFilterAttribute都可以實現使用者授權的功能。
AuthorizeAttribute和ActionFilterAttribute
AuthorizeAttribute這個過濾器從字面上就可以看出它的功能,它主要用在使用者角色授權上,對於我們的系統來說,那就是哪些頁面需要登陸,就把哪個Action新增這個特性,它有方法OnAuthorization,表示當頁面載入之前,去判斷使用者是否有訪問本action的許可權,我們可以根據自己的需要去override它;ActionFilterAttribute過濾器是我們平時用的最多的,即在action執行前,後,View渲染前,渲染後的跟蹤,我們在使用時,重寫對應的方法,即可以實現對各個步驟的跟蹤。
實現原理,方法攔截
在mvc裡,過濾器的含義就是方法攔截,這個概念和Aop不某而合,都是對方法進行攔截,然後進行二次加工,過濾器的原理也一樣,在進行攔截後,可以去填充你自己的業務邏輯,然後選擇繼續渲染還是離開頁面。
AuthorizationLoginFilter過濾器的實現
下面是我自己整理的,使用者授權的一個過濾器,分享一下
/// <summary> /// 授權過濾器 /// Function:MVC模式下使用 /// Author:Lind.zhang /// </summary> public class AuthorizationLoginFilter : AuthorizeAttribute {/// <summary> /// 驗證失敗後所指向的控制器和action /// 可以在使用特性時為它進行賦值 /// </summary> public AuthorizationLoginFilter(string failControllerName = "Home", string failActionName = "Login") { _failControllerName = failControllerName; _failActionName= failActionName; } public string _failControllerName, _failActionName; public override void OnAuthorization(AuthorizationContext filterContext) { //被新增AllowAnonymousAttribute特性的過濾器將不參加AuthorizationLoginFilter的驗證 bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true); //為登陸頁新增例外,其它頁都自動在global.asax裡新增到全域性過濾器中,MVC3及以後版本支援它 if (!skipAuthorization) { if (!CurrentUser.IsLogin) { filterContext.Result = new RedirectToRouteResult("Default", new RouteValueDictionary { { "Action",_failActionName }, { "Controller", _failControllerName}, { "returnUrl", HttpContext.Current.Request.Url.ToString() } }); } } } }
授權模組的CurrentUser的實現
對於過濾器把沒有登陸的使用者指引登陸頁後,使用者將進行登陸操作,然後Lind.DDD要做什麼?需要將使用者標示,角色資訊,許可權資訊進行儲存,這時就是我們CurrentUser登場的時候了,設計很簡單,一個方法用來持久化使用者授權的物件,幾個屬性用來返回需要返回的內容,呵呵 !
/// <summary> /// 當前登陸的使用者資訊 /// 可以有Redis Session和Session進行實現 /// </summary> public class CurrentUser { #region Public Properties /// <summary> /// 當然登陸的使用者ID /// </summary> public static string UserID { get { return (System.Web.HttpContext.Current.Session["UserID"] ?? string.Empty).ToString(); } } /// <summary> /// 當前登陸的使用者名稱 /// </summary> public static string UserName { get { return (System.Web.HttpContext.Current.Session["UserName"] ?? string.Empty).ToString(); } } /// <summary> /// 使用者角色 /// </summary> public static string Role { get { return (System.Web.HttpContext.Current.Session["Role"] ?? string.Empty).ToString(); } } /// <summary> /// 使用者許可權 /// 增,刪,改,查 /// </summary> public static string Authority { get { return (System.Web.HttpContext.Current.Session["Authority"] ?? string.Empty).ToString(); } } /// <summary> /// 當前登陸使用者儲存的擴充套件資訊 /// </summary> public static string ExtInfo { get { return (System.Web.HttpContext.Current.Session["ExtInfo"] ?? string.Empty).ToString(); } } /// <summary> /// 是否登陸 /// </summary> public static bool IsLogin { get { return !string.IsNullOrWhiteSpace(UserID); } } #endregion #region Public Methods /// <summary> /// 退出登陸 /// </summary> public static void Exit() { System.Web.HttpContext.Current.Session.Abandon();//清除全部Session } /// <summary> /// 將使用者資訊持久化到Session /// </summary> /// <param name="userID"></param> /// <param name="userName"></param> /// <param name="ExtInfo"></param> public static void Serialize( string userID, string userName, string extInfo = "", string role = "", string authority = "") { System.Web.HttpContext.Current.Session["UserID"] = userID; System.Web.HttpContext.Current.Session["UserName"] = userName; System.Web.HttpContext.Current.Session["ExtInfo"] = ExtInfo; System.Web.HttpContext.Current.Session["Role"] = role; System.Web.HttpContext.Current.Session["Authority"] = authority; }