• 自定义AuthorizeAttribute实现MVC权限设计


    文本为您介绍:自定义AuthorizeAttribute实现MVC权限设计,主要是通过将角色与controller、action等参数关联进行用户权限判断,然后通过自定义AuthorizeAttribute来实现实现这一功能,同时根据情况会对一些规则进行一些调整,下面请看内容:

    简明需求

    1、可以对每个action实现权限控制,并且可以在数据库动态配置

    2、权限分为允许所有人访问、允许注册用户访问、允许\禁止特定角色人访问

    数据库设计

    image

    在demo里不使用数据库,这里给出表对应的类

    /// 
        /// 控制器和Action
        /// 
        public class ControllerAction
        {
            public int Id
            {
                get;
                set;
            }
    
            public string Name
            {
                get;
                set;
            }
    
            /// 
            /// IsController是指是否是controller,如果为false,
            /// 表示是action,那么controllerName字段就派上用场了
            /// 
            public bool IsController
            {
                get;
                set;
            }
    
            /// 
            /// 控制器名称
            /// 如果IsController为false,该项不能为空
            /// 
            public string ControllName
            {
                get;
                set;
            }
    
            /// 
            /// 是指是否允许没有权限的人访问 
            /// 
            public bool IsAllowedNoneRoles
            {
                get;
                set;
            }
    
            /// 
            /// 是否允许有角色的人访问 
            /// 
            public bool IsAllowedAllRoles
            {
                get;
                set;
            }
        }
    
        /// 
        /// 用户与角色的关联表
        /// 
        public class ControllerActionRole
        {
            public int Id
            {
                get;
                set;
            }
    
            /// 
            /// 对应的ControllerAction编号
            /// 
            public int ControllerActioId
            {
                get;
                set;
            }
    
            /// 
            /// 对应的角色编号
            /// 
            public int RoleId
            {
                get;
                set;
            }
    
            /// 
            /// IsAllowed表示包含RoleId的用户是否有权限访问ControllerActioId
            /// 
            public bool IsAllowed
            {
                get;
                set;
            }
        }
    
        /// 
        /// 角色
        /// 
        public class Role
        {
            public int Id
            {
                get;
                set;
            }
    
            public string Name
            {
                get;
                set;
            }
    
            public string Description
            {
                get;
                set;
            }
        }
    
        /// 
        /// 用户
        /// 
        public class User
        {
            public int Id
            {
                get;
                set;
            }
    
            public string Name
            {
                get;
                set;
            }
        }
    
        /// 
        /// 用户与角色的关联表
        /// 
        public class UserRole
        {
            public int Id
            {
                get;
                set;
            }
            public int UserId
            {
                get;
                set;
            }
            public int RoleId
            {
                get;
                set;
            }
        }

    核心流程

    image

    我们见一个Database类来模拟数据库

    /// 
           /// 
        /// 模拟数据库
        /// 
        public class Database
        {
            public static List Users;
            public static List Roles;
            public static List UserRoles;
            public static List ControllerActions;
            public static List ControllerActionRoles;
    
            static Database()
            {
                // 初始化用户
                Users = new List()
                {
                    new User(){Id=1,Name="Admin"},
                    new User(){Id=2,Name ="User"},
                    new User(){Id=3,Name="Guest"}
                };
    
                Roles = new List()
                {
                    new Role() {Id=1,Name="Administrator"},
                    new Role() {Id=2,Name="User"}
                };
    
                UserRoles = new List()
                {
                     new UserRole(){Id=1,RoleId=1,UserId=1}, //管理员
                     new UserRole(){Id=2,RoleId=2,UserId=2} //用户
                };
    
                ControllerActions = new List()
                {
                    new ControllerAction(){Id=1,Name="Index",IsController=true,IsAllowedNoneRoles=true,IsAllowedAllRoles=true}, // /Home 允许所有人访问
    
                    new ControllerAction(){Id=2,ControllName="Home",Name="Admin",IsController=false,IsAllowedNoneRoles=false,IsAllowedAllRoles = false}, // /Home/Admin 管理员才能访问
    
                    new ControllerAction(){Id=3,ControllName="Home",Name="User",IsController=false,IsAllowedNoneRoles=false,IsAllowedAllRoles = true}, // /Home/User 有角色的人才能访问
                    
                    new ControllerAction(){Id=4,ControllName="Home",Name="UserOnly",IsController=false,IsAllowedNoneRoles=false,IsAllowedAllRoles = false}, // /Home/UserOnly 用户才能访问
    
                };
    
                ControllerActionRoles = new List() { 
                    new ControllerActionRole(){ Id=1,ControllerActioId = 2,RoleId = 1,IsAllowed = true },  // 管理员才能访问
                    new ControllerActionRole(){ Id=2,ControllerActioId = 4,RoleId = 2,IsAllowed = true }  // USER才能访问
                };
    
            }
        }
      

    来看我们的主要代码

          /// 
        /// 自定义AuthorizeAttribute
        /// 
        public class UserAuthorizeAttribute : AuthorizeAttribute
        {
    
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                var user = filterContext.HttpContext.Session["CurrentUser"] as User;
    
                // 用户为空,赋予Guest
                if (user == null)
                {
                    user = Database.Users.Find(u => u.Name == "Guest");
                }
    
                var controller = filterContext.RouteData.Values["controller"].ToString();
                var action = filterContext.RouteData.Values["action"].ToString();
                var isAllowed = this.IsAllowed(user, controller, action);
    
                if (!isAllowed)
                {
                    filterContext.RequestContext.HttpContext.Response.Write("无权访问");
                    filterContext.RequestContext.HttpContext.Response.End();
                }
    
            }
    
            /// 
            /// 判断是否允许访问
            /// 
            ///  用户
            ///  控制器
            ///  action
            /// 是否允许访问
            public bool IsAllowed(User user, string controller, string action)
            {
    
                // 找controllerAction
                var controllerAction = Database.ControllerActions.Find(ca => ca.IsController == false && ca.Name == action && ca.ControllName == controller);
    
                //action无记录,找controller
                if (controllerAction == null)
                {
                    controllerAction = Database.ControllerActions.Find(ca => ca.IsController && ca.Name == controller);
                }
    
                // 无规则
                if (controllerAction == null)
                {
                    return true;
                }
    
    
                // 允许没有角色的:也就是说允许所有人,包括没有登录的用户 
                if (controllerAction.IsAllowedNoneRoles)
                {
                    return true;
                }
    
                // 允许所有角色:只要有角色,就可以访问 
                if (controllerAction.IsAllowedAllRoles)
                {
                    var roles = Database.UserRoles.FindAll(ur => ur.UserId == user.Id);
                    if (roles.Count > 0)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
    
    
                // 选出action对应的角色 
                var actionRoles = Database.ControllerActionRoles.FindAll(ca => ca.ControllerActioId == controllerAction.Id).ToList();
    
                if (actionRoles.Count == 0)
                {
                    // 角色数量为0,也就是说没有定义访问规则,默认允许访问 
                    return true;
                }
    
                var userHavedRolesids = Database.UserRoles.FindAll(ur => ur.UserId == user.Id).Select(ca => ca.RoleId).ToList();
    
                // 查找禁止的角色 
                var notAllowedRoles = actionRoles.FindAll(r => !r.IsAllowed).Select(ca => ca.RoleId).ToList();
                if (notAllowedRoles.Count > 0)
                {
                    foreach (int roleId in notAllowedRoles)
                    {
                        // 用户的角色在禁止访问列表中,不允许访问 
                        if (userHavedRolesids.Contains(roleId))
                        {
                            return false;
                        }
                    }
                }
    
                // 查找允许访问的角色列表 
                var allowRoles = actionRoles.FindAll(r => r.IsAllowed).Select(ca => ca.RoleId).ToList();
                if (allowRoles.Count > 0)
                {
                    foreach (int roleId in allowRoles)
                    {
                        // 用户的角色在访问的角色列表 
                        if (userHavedRolesids.Contains(roleId))
                        {
                            return true;
                        }
                    }
                }
    
                // 默认禁止访问
                return false;
            }
    
        }
      

    测试

        [HandleError]
        [UserAuthorize]
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                ViewData["Message"] = "欢迎使用 ASP.NET MVC!";
    
                return View();
            }
            public ActionResult Admin()
            {
                ViewData["Message"] = "只有管理员才能访问!";
    
                return View("Index");
            }
            public ActionResult User()
            {
                ViewData["Message"] = "只要是注册用户就能访问!";
    
                return View("Index");
            }
            public ActionResult UserOnly()
            {
                ViewData["Message"] = "只能是User才能能访问!";
    
                return View("Index");
            }
    
            public ActionResult Login(string user)
            {
                Session["CurrentUser"] = Database.Users.Find(u => u.Name == user);
                if (Session["CurrentUser"] != null)
                {
                    ViewData["Message"] = "你已登录为" + user;
                }
    
                return View("Index");
            }
    
    
            public ActionResult About()
            {
                return View();
            }
        }

    1、登录为Admin

    image

    访问Admin

    image

    访问User

    image

    访问UserOnly

    image

    2、登录为User

    image

    访问Admin

    image

    访问User

    image

    访问UserOnly

    image

    demo下载 MVCRole.rar

    文章内容自定义AuthorizeAttribute实现MVC权限设计就此结了,大伙可寻得源码研究。

  • 相关阅读:
    事务的传播特性及事务的并发
    Spring 配置文件配置事务
    Spring 配置文件AOP
    Spring 注解形式AOP
    Spring与Junit测试整合
    Spring基础知识1--环境搭建、bean创建、依赖注入、注解注入
    JDK动态代理与CGLIB动态代理
    java.lang.illegalArgumentException异常
    计算器
    list
  • 原文地址:https://www.cnblogs.com/dyg540/p/2457376.html
Copyright © 2020-2023  润新知