首页 > 代码库 > Asp.Net MVC 权限控制(三):Controller和Action级别控制

Asp.Net MVC 权限控制(三):Controller和Action级别控制

 续接上篇: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 =http://www.mamicode.com/="")            {                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