Asp.Net MVC 許可權控制(三):Controller和Action層級控制

來源:互聯網
上載者:User

標籤:des   style   blog   http   strong   資料   

 續接上篇:Asp.Net MVC 許可權控制(二):Controller層級控制

 

再次在重構!這次對Controller和Action進行驗證。

思路:系統有很多功能集,功能集對應很多Controller和Action角色指派很多功能集


首先構建一個基礎資料:

1.功能集初始化:

  /// <summary>    /// 系統模組    /// </summary>    public class SystemModule    {        public SystemModule()        {            this.ID = Guid.NewGuid();        }        public Guid ID { get; set; }        public string Name { get; set; }        public string Description { get; set; }        public SystemModule Parent { get; set; }        public List<SystemModuleController> SystemModuleControllers { get; set; }        public static List<SystemModule> Init()        {            var m1 = new SystemModule { Name = "資源監測" };            var m2 = new SystemModule { Name = "規劃管理" };            var c1 = new SystemModuleController { ControllerName = "PlanManagement", ActionName = "Search" };            var c2 = new SystemModuleController { ControllerName = "PlanManagement", ActionName = "Add" };            var c3 = new SystemModuleController { ControllerName = "PlanManagement", ActionName = "Edit" };            var c4 = new SystemModuleController { ControllerName = "PlanManagement", ActionName = "Delete" };            var c5 = new SystemModuleController { ControllerName = "PlanManagement", ActionName = "Approval" };            var m21 = new SystemModule { Name = "規劃資訊查詢", Parent = m2, SystemModuleControllers = new List<SystemModuleController> { c1 } };            var m22 = new SystemModule { Name = "規劃資訊管理", Parent = m2, SystemModuleControllers = new List<SystemModuleController> { c2, c3, c4 } };            var m23 = new SystemModule { Name = "規劃輔助審批", Parent = m2, SystemModuleControllers = new List<SystemModuleController> { c5 } };            return new List<SystemModule> { m1, m2, m12, m21, m22, m23 };        }    }

 2.角色初始化:

    /// <summary>    /// 角色    /// </summary>    public class SystemRole    {        public SystemRole()        {            this.ID = Guid.NewGuid();        }        public Guid ID { get; set; }        public string Name { get; set; }        public string Description { get; set; }        public List<SystemModule> SystemModules { get; set; }        public static SystemRole Init(string[] roles)        {            var modules = SystemModule.Init();            var systemModules = roles.Select(r => modules.FirstOrDefault(m => m.Name == r)).ToList();            var role = new SystemRole { Name = "預設角色", SystemModules = systemModules };            return role;        }    }

3. 系統所有Controller和Action的讀取

 /// <summary>    /// 讀取系統的所有Controller和Action    /// </summary>    public class SystemModuleController    {        public SystemModuleController()        {            this.ID = Guid.NewGuid();        }        public Guid ID { get; set; }        public string ModuleName { get; set; }        public string ControllerName { get; set; }        public string ActionName { get; set; }        public string Description { get; set; }        public List<SystemModuleController> SystemModuleActions { get; set; }        public static List<SystemModuleController> GetSystemModuleController()        {            var systemModuleControllers = new List<SystemModuleController>();            // 讀取項目中的Controller            var types = Assembly.Load("PRMMS.Authorization").GetTypes().Where(b => b.BaseType != null && b.BaseType.Name == "BaseController");            foreach (var type in types)            {                // 標記需要許可權驗證的Controller                var modules = type.GetCustomAttributes(typeof(ModuleAuthorizationAttribute), true);                if (modules.Length == 1)                {                    // Controller名稱                    var controllerName = type.Name.Replace("Controller", "");                    // Controller描述                    var description = string.Empty;                    var attrs = type.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true);                    if (attrs.Length > 0)                    {                        description = (attrs[0] as System.ComponentModel.DescriptionAttribute).Description;                    }                    // 擷取Controller下的Action                    var systemModuleControllerAction = new List<SystemModuleController>();                    var actions = type.GetMethods().Where(a => a.ReturnType != null && a.ReturnType.Name == "ActionResult");                    foreach (var action in actions)                    {                        // Action名稱                        var actionName = action.Name;                        // Action描述                        var desc = string.Empty;                        var act = action.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true);                        if (act.Length > 0)                        {                            desc = (act[0] as System.ComponentModel.DescriptionAttribute).Description;                        }                        systemModuleControllerAction.Add(new SystemModuleController                                                             {                                                                 ControllerName = controllerName,                                                                 ActionName = actionName,                                                                 Description = desc                                                             });                    }                    var systemModule = new SystemModuleController                    {                        ControllerName = controllerName,                        Description = description,                        SystemModuleActions = systemModuleControllerAction                    };                    systemModuleControllers.Add(systemModule);                }            }            return systemModuleControllers;        }    }

  

系統登入後,初始化許可權並儲存緩衝中。

        [HttpPost]        [ValidateAntiForgeryToken]        public ActionResult Login(LoginModel model, string returnUrl)        {            var userName = model.UserName;            FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(            1,            userName,            DateTime.Now,            DateTime.Now.AddMinutes(20),            false,            model.Roles.Aggregate((i, j) => i + "," + j)            );            string encryptedTicket = FormsAuthentication.Encrypt(authTicket);            var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);            System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);            // 初始化許可權            var systemRole = SystemRole.Init(model.Roles);            // 緩衝許可權            AccountHelper.AddCache(systemRole.SystemModules);            return RedirectToAction("Index", "Home");        }

  AccountHelper:

    public class AccountHelper    {        private const string CacheName = "SystemModules";        /// <summary>        /// 擷取使用者資訊        /// </summary>        /// <returns></returns>        public static FormsAuthenticationTicket GetCookieUser()        {            HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];            if (authCookie == null || authCookie.Value == "")            {                return null;            }            try            {                return FormsAuthentication.Decrypt(authCookie.Value);            }            catch (Exception ex)            {                return null;            }        }        /// <summary>        /// 添加緩衝        /// </summary>        /// <param name="systemModules"></param>        public static void AddCache(List<SystemModule> systemModules)        {            HttpContext.Current.Cache[CacheName] = systemModules;        }        /// <summary>        /// 讀取緩衝        /// </summary>        /// <returns></returns>        public static List<SystemModule> GetCache()        {            if (HttpContext.Current.Cache[CacheName] == null)            {                // 重新構建許可權                var user = GetCookieUser();                var roles = user.UserData.Split(new[] { ‘,‘ });                HttpContext.Current.Cache[CacheName] = SystemRole.Init(roles).SystemModules;            }            return (List<SystemModule>)HttpContext.Current.Cache[CacheName];        }        /// <summary>        /// 驗證Controller和Action        /// </summary>        /// <param name="controllerName"></param>        /// <param name="actionName"></param>        /// <returns></returns>        public static bool ValidatePermission(string controllerName, string actionName)        {            var systemModules = GetCache();            foreach (var systemModule in systemModules)            {                if (systemModule != null && systemModule.SystemModuleControllers != null)                {                    foreach (var controller in systemModule.SystemModuleControllers)                    {                        if (controller.ControllerName == controllerName && controller.ActionName == actionName) return true;                    }                }            }            return false;        }    }

  

同樣在業務的Controller添加攔截標記

    [LoginAllow]    [PermissionFilter]    public class BaseController : Controller    {    }    [Description("規劃管理控制器")]    [ModuleAuthorization]    public class PlanManagementController : BaseController    {        [Description("首頁")]        public ActionResult Index()        {            return View();        }        [Description("查詢")]        public ActionResult Search()        {            return View();        }        [Description("添加")]        public ActionResult Add()        {            return View();        }        [Description("編輯")]        public ActionResult Edit()        {            return View();        }        [Description("刪除")]        public ActionResult Delete()        {            return View();        }        [Description("審批")]        public ActionResult Approval()        {            return View();        }    }

  

攔截器:PermissionFilterAttribute

  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]    public class PermissionFilterAttribute : ActionFilterAttribute    {        // OnActionExecuted 在執行操作方法後由 ASP.NET MVC 架構調用。        // OnActionExecuting 在執行操作方法之前由 ASP.NET MVC 架構調用。        // OnResultExecuted 在執行操作結果後由 ASP.NET MVC 架構調用。        // OnResultExecuting 在執行操作結果之前由 ASP.NET MVC 架構調用。        /// <summary>        /// 在執行操作方法之前由 ASP.NET MVC 架構調用。        /// </summary>        /// <param name="filterContext"></param>        public override void OnActionExecuting(ActionExecutingContext filterContext)        {            //fcinfo = new filterContextInfo(filterContext);            //根據驗證判斷進行處理            if (!this.AuthorizeCore(filterContext))            {                filterContext.RequestContext.HttpContext.Response.Redirect("~/Account/Login");            }        }        /// <summary>        /// //許可權判斷商務邏輯        /// </summary>        /// <param name="filterContext"></param>        /// <returns></returns>        protected virtual bool AuthorizeCore(ActionExecutingContext filterContext)        {            object[] filter;            // 驗證當前Action是否是匿名訪問Action            filter = filterContext.Controller.GetType().GetCustomAttributes(typeof(AnonymousAttribute), true);            if (filter.Length == 1)            {                return true;            }            // 驗證當前Action是否是許可權控制頁面Action            filter = filterContext.Controller.GetType().GetCustomAttributes(typeof(ModuleAuthorizationAttribute), true);            if (filter.Length == 1)            {                //擷取 controllerName 名稱                var controllerName = filterContext.RouteData.Values["controller"].ToString();                //擷取ACTION 名稱                var actionName = filterContext.RouteData.Values["action"].ToString();                return AccountHelper.ValidatePermission(controllerName, actionName);            }            // 驗證當前Action是否是登入使用者Action            filter = filterContext.Controller.GetType().GetCustomAttributes(typeof(LoginAllowAttribute), true);            if (filter.Length == 1)            {                return HttpContext.Current.User.Identity.IsAuthenticated;            }            throw new Exception("使用者驗證失敗!");        }    }

  

 

代碼下載:PRMMS.Authorization.zip

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.