自定义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权限设计

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

你可能感兴趣的:(attribute)