续接上篇:Asp.Net MVC 权限控制(二):Controller级别控制
再次在重构!这次对Controller和Action进行验证。
思路:系统有很多功能集,功能集对应很多Controller和Action,角色分配很多功能集。
首先构建一个基础数据:
1.功能集初始化:
class="brush:csharp;gutter:true;"> /// <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