asp.net MVC 許可權設計(續)

來源:互聯網
上載者:User
文章目錄
  • 簡明需求
  • 資料庫設計
  • 核心流程
  • 測試

asp.net MVC 許可權設計一文中沒有demo放出來,應大家的要求,這裡補充上文並放出demo。

 

幾點說明:

 

    1、基於將角色與controller、action相關聯來判斷使用者是否有權

    2、通過自訂AuthorizeAttribute實現

    3、demo 僅供參考,一些規則可以根據實際情況重新定義

 

簡明需求

1、可以對每個action實現許可權控制,並且可以在資料庫動態配置

2、許可權分為允許所有人訪問、允許註冊使用者訪問、允許\禁止特定角色人訪問

 

資料庫設計

 

在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;        }    }
核心流程

 

我們見一個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

 

訪問Admin

 

訪問User

 

訪問UserOnly

 

2、登入狀態User

 

訪問Admin

 

訪問User

訪問UserOnly

 

demo下載 MVCRole.rar

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.