[转载]Asp.Net MVC 权限控制(三):Controller和Action级别控制 – Jetlian – 博客园

来源: [转载]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]

 

代码下载:PRMMS.Authorization.zip