ASP.netMVC基于角色的权限控制系统的实现

ASP.netMVC基于角色的权限控制系统的实现

2023年6月20日发(作者:)

基于⾓⾊的权限控制系统的实现⼀、引⾔我们都知道 mvc权限控制都是实现AuthorizeAttribute类的OnAuthorization⽅法。下⾯是最常见的实现⽅式: public class CustomAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { if (!enticated) { = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "account", action = "login", returnUrl = , returnMessage = "您⽆权查看." })); return; } orization(filterContext); }}然后在需要验证的Action上打上[CustomAuthorize]标签就可以了。这种⽅式是⽐较粗粒度的解决⽅案,由于是已经将定义好(约定好的)权限hard code带对应的Action上,所以⽆法实现⽤户⾃定义权限控制。看⼀下代码:using System;using c;using ;using ;using ;namespace llers{ public class UserController : Controller { [UserAuthorize] public ActionResult Index() { return View(); } [AdminAuthorize] public ActionResult Admin() { return View(); } [UserAuthorize] public ActionResult Detail() { return View(); } }}我们有⼀个UserController,他有3个Action:Index,Admin,Detail.其中Admin需要系统管理员权限,其他两个值需要User权限。这样就需要建⽴AdminAuthorizeAttribute和UserAuthorizeAttribute.这样做就⽆法实现⽤户⾃定义权限。⼆、基于⾓⾊的权限控制系统基于⾓⾊的权限控制系统RBAC(Role Based Access Control)是⽬前最流⾏,也是最通⽤的权限控制系统。对于 MVC来说,这套系统很容易实现:Controller下的每⼀个Action可以看作是⼀个权限,⾓⾊就相当于多个权限的组合。然后我们新建⼀个RoleAuthorizeAttribute,即对⾓⾊的属性描述。2.1 如何鉴权这个RoleAuthorizeAttribute的关键在于如何拿到ControllerName和ActionName,查阅msdn其实很容易就实现了,不多说,直接上代码:using System;using c;using ;using ;using ty;using ;using g;using es;namespace utes{ public class RoleAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { var isAuth = false; if (!enticated) { isAuth = false; } else { if (ty != null) { var roleService = new RoleService(); var actionDescriptor = Descriptor; var controllerDescriptor = llerDescriptor; var controller = llerName; var action = Name; var ticket = (ty as FormsIdentity).Ticket; var role = d(n); if (role != null) { isAuth = (x => r() == r() && r() == r()); } } } if (!isAuth) { = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "account", action = "login", returnUrl = , returnMessage = "您⽆权查看." })); return; } else { orization(filterContext); } } }}注意:这⾥⽤Ticket的Version存储RoleId。你也可以⽤其他⽅式。主要是⽤到了 Descriptor和Descriptor。2.2 如何⽣成权限控制列表前⾯的sions的集合已经是定义好的权限列表。Permissions类的定义如下:using System;using c;using ;using ;namespace es{ public class PermissionDefinition { public virtual int Id { set; get; } public virtual int ActionNo { set; get; } public virtual int ControllerNo { set; get; } public virtual string Name { set; get; } public virtual string ControllerName { set; get; } public virtual string Controller { set; get; } public virtual string Action { set; get; } public virtual DateTime AddDate { set; get; } }}属性Controller和Action记录的是权限,ControllerName和ActionName⽤于显⽰UI,ControllerNo和ActionNo⽤于显⽰顺序控制。这⾥你可以⼿⼯将所有Action录⼊数据库中,然后实现RolService即可。但是显然这种⽅法实在是太笨了,我们其实可以⽤反射+Attribute机制实现⾃动化载⼊权限控制表。原理很简单,我就直接上关键代码了。以下是反射的代码:using System;using c;using ;using ;using ;using es;using utes;using es;namespace llers{ public class InstallController : Controller { public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index() { try { var roleService = new RoleService(); #region init permission createPermission(new UserController()); #endregion var allDefinedPermissions = inedPermissions(); #region 超级管理员⾓⾊初始化 var adminPermissions = new List(); foreach (var d in allDefinedPermissions) { (new RolePermissionInfo { AddDate = , Permission = d, }); } int adminRoleId = e(new fo { AddDate = , Description = "", Name = "超级管理员", Permissions = adminPermissions }); #endregion return RedirectToAction("Admin", "User"); } catch (Exception ex) { elError("", e); return View(); } } private void createPermission(Controller customController) { var roleService = new RoleService(); var controllerName = ""; var controller = ""; var controllerNo = 0; var actionName = ""; var action = ""; var actionNo = 0; var controllerDesc = new KeyValuePair(); var controllerType = e(); controller = e("Controller", "");//remobe controller posfix controllerDesc = getdesc(controllerType); if (!OrEmpty()) { controllerName = ; controllerNo = ; foreach (var m in hods()) { var mDesc = getPropertyDesc(m); if (OrEmpty()) continue; action = ; actionName = ; actionNo = ; Permissions(actionNo, controllerNo, actionName, controllerName, controller, action); } } } private KeyValuePair getdesc(Type type) { var descriptionAttribute = (DescriptionAttribute)(tomAttributes(false).FirstOrDefault(x => x is DescriptionAttribute)); if (descriptionAttribute == null) return new KeyValuePair(); return new KeyValuePair(, ); } private KeyValuePair getPropertyDesc(Info type) { var descriptionAttribute = (DescriptionAttribute)(tomAttributes(false).FirstOrDefault(x => x is DescriptionAttribute)); if (descriptionAttribute == null) return new KeyValuePair(); return new KeyValuePair(, ); } }}以下是DescriptionAttribute的代码:using System;using c;using ;using ;namespace utes{ public class DescriptionAttribute : Attribute { public string Name { set; get; } public int No { set; get; } }}然后在UserController打上DescriptionAttribute标签就可以了,如下所⽰:using System;using c;using ;using ;using ;using utes;namespace llers{ [Description(No = 1, Name = "⽤户")] public class UserController : Controller { [RoleAuthorize] [Description(No = 1, Name = "⽤户⾸页")] public ActionResult Index() { return View(); } [RoleAuthorize] [Description(No = 1, Name = "⽤户管理")] public ActionResult Admin() { return View(); } [RoleAuthorize] [Description(No = 1, Name = "⽤户详情")] public ActionResult Detail() { return View(); } }}样在⽹站安装的时候直接执⾏Install就可以完全⾃动化创建权限。这样就可以精确到每个Action的⽤户⾃定义权限控制了。看看我的劳动成果:写在最后:对于同名的Action的HttpGET和HttpPOST分成两个权限还没有实现。⽐如说:New[HttpGet],和New[HttpPOST]。主要是觉得这样没有太⼤的意义,当然如果你的业务需求必须这样,我觉得应该很容易就能扩展。PS:代码只有关键代码,没有实现RoleService⽅法,请⾃⾏根据⾃⼰的实际情况实现。

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687249823a25.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信