[转载]Asp.Net MVC 权限控制(三):Controller和Action级别控制 – Jetlian – 博客园
- ASP.NET MVC
- 2015-06-09
- 96热度
- 0评论
来源: [转载]Asp.Net MVC 权限控制(三):Controller和Action级别控制 - Jetlian - 博客园
再次在重构!这次对Controller和Action进行验证。
思路:系统有很多功能集,功能集对应很多Controller和Action,角色分配很多功能集。
首先构建一个基础数据:
1.功能集初始化:
[code]
/// <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 }; } }[/code]
2.角色初始化:
[code]
/// <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; }}[/code]
3. 系统所有Controller和Action的读取
[code]
/// <summary> /// 读取系统的所有Controller和Action /// </summary> publicclassSystemModuleController { publicSystemModuleController() { this.ID = Guid.NewGuid(); } publicGuid ID { get; set; } publicstringModuleName { get; set; } publicstringControllerName { get; set; } publicstringActionName { get; set; } publicstringDescription { get; set; } publicList<SystemModuleController> SystemModuleActions { get; set; } publicstaticList<SystemModuleController> GetSystemModuleController() { varsystemModuleControllers = newList<SystemModuleController>(); // 读取项目中的Controller vartypes = Assembly.Load("PRMMS.Authorization").GetTypes().Where(b => b.BaseType != null&& b.BaseType.Name == "BaseController"); foreach(vartype intypes) { // 标记需要权限验证的Controller varmodules = type.GetCustomAttributes(typeof(ModuleAuthorizationAttribute), true); if(modules.Length == 1) { // Controller名称 varcontrollerName = type.Name.Replace("Controller", ""); // Controller描述 vardescription = string.Empty; varattrs = type.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true); if(attrs.Length > 0) { description = (attrs[0] asSystem.ComponentModel.DescriptionAttribute).Description; } // 获取Controller下的Action varsystemModuleControllerAction = newList<SystemModuleController>(); varactions = type.GetMethods().Where(a => a.ReturnType != null&& a.ReturnType.Name == "ActionResult"); foreach(varaction inactions) { // Action名称 varactionName = action.Name; // Action描述 vardesc = string.Empty; varact = action.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true); if(act.Length > 0) { desc = (act[0] asSystem.ComponentModel.DescriptionAttribute).Description; } systemModuleControllerAction.Add(newSystemModuleController { ControllerName = controllerName, ActionName = actionName, Description = desc }); } varsystemModule = newSystemModuleController { ControllerName = controllerName, Description = description, SystemModuleActions = systemModuleControllerAction }; systemModuleControllers.Add(systemModule); } } returnsystemModuleControllers; } }[/code]
系统登录后,初始化权限并保存缓存中。
[code]
[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");}[/code]
AccountHelper:
[code]
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; }}[/code]
同样在业务的Controller添加拦截标记
[code]
[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(); }}[/code]
拦截器:PermissionFilterAttribute
[code]
[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("用户验证失败!"); } }[/code]
