asp.net MVC 权限设计(续)
asp.net MVC 权限设计一文中没有demo放出来,应大家的要求,这里补充上文并放出demo。
几点说明:#
1、基于将角色与controller、action相关联来判断用户是否有权
2、通过自定义AuthorizeAttribute实现
3、demo 仅供参考,一些规则可以根据实际情况重新定义
简明需求#
数据库设计#
在demo里不使用数据库,这里给出表对应的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | /// /// 控制器和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类来模拟数据库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /// /// /// 模拟数据库 /// 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
关注作者
作者: JadePeng
出处:https://www.cnblogs.com/xiaoqi/archive/2011/01/24/1942880.html
版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际(欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接) 」知识共享许可协议进行许可。
分类:
ASP.NET编程
标签:
ASP.NET MVC
, 权限设计
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库