文章出處

回到目錄

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;

        }
        #endregion

    }

OK,對于Lind.DDD.Authorization用戶授權這塊就說到這里,如果對大家有幫助,請您點個贊吧!

回到目錄

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()