asp.net MVC 权限设计(续)

asp.net MVC 权限设计一文中没有demo放出来,应大家的要求,这里补充上文并放出demo。

 

几点说明:

 

    1、基于将角色与controller、action相关联来判断用户是否有权

    2、通过自定义AuthorizeAttribute实现

    3、demo 仅供参考,一些规则可以根据实际情况重新定义

 

简明需求

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

你可能感兴趣的:(asp.net)