博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MVC 自定义AuthorizeAttribute实现权限管理
阅读量:6305 次
发布时间:2019-06-22

本文共 4737 字,大约阅读时间需要 15 分钟。

在上一节中提到可以使用AuthorizeAttribute进行权限管理:

[Authorize]        public ActionResult TestAuthorize()        {             return View();        }        [Authorize(Users="test1,test2")]        public ActionResult TestAuthorize()        {             return View();        }        [Authorize(Roles="Admin")]        public ActionResult TestAuthorize()        {             return View();        }

但是通常情况下,网站的权限并不是固定不变的,当新增角色或者角色改变时,只能修改每个Action对应的特性,当项目较大时工作量可想而知。幸运的是我们可以重写AuthorizeAttribute达到自定义的权限管理。新建一个CustomAuthorizeAttribute类,使这个类继承于AuthorizeAttribute。打开AuthorizeAttribute查看下方法说明,我们只需要重写AuthorizeCore和OnAuthorization就能达到我们的目的。

 

// Summary:        //     When overridden, provides an entry point for custom authorization checks.        //        // Parameters:        //   httpContext:        //     The HTTP context, which encapsulates all HTTP-specific information about        //     an individual HTTP request.        //        // Returns:        //     true if the user is authorized; otherwise, false.        //        // Exceptions:        //   System.ArgumentNullException:        //     The httpContext parameter is null.        protected virtual bool AuthorizeCore(HttpContextBase httpContext);//        // Summary:        //     Called when a process requests authorization.        //        // Parameters:        //   filterContext:        //     The filter context, which encapsulates information for using System.Web.Mvc.AuthorizeAttribute.        //        // Exceptions:        //   System.ArgumentNullException:        //     The filterContext parameter is null.        public virtual void OnAuthorization(AuthorizationContext filterContext);

 

 

在CustomAuthorizeAttribute中重载AuthorizeCore方法,它的处理逻辑如下:首先判断当前账户是否被认证,如果没有,则返回false;然后获取当前账户的类型,并跟给定的类型进行比较,如果类型相同,则返回true,否则返回false。一般网站中权限管理都会使用权限树,然后将角色的权限保存至数据库或者文件中,本例中我们使用XML文件保存每个Action的角色,这样在用户请求Action时,由XML文件获取Action对应的权限,然后检测账户是否有相应的权限。CustomAuthorizeAttribute类的代码如下:

 

public class CustomAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute    {        public new string[] Roles { get; set; }        protected override bool AuthorizeCore(HttpContextBase httpContext)        {            if (httpContext == null) {                throw new ArgumentNullException("HttpContext");            }            if (!httpContext.User.Identity.IsAuthenticated) {                return false;            }            if (Roles == null) {                return true;            }            if (Roles.Length == 0)            {                return true;            }            if (Roles.Any(httpContext.User.IsInRole))            {                return true;            }            return false;        }        public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)        {            string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;            string actionName = filterContext.ActionDescriptor.ActionName;            string roles = GetRoles.GetActionRoles(actionName, controllerName);            if (!string.IsNullOrWhiteSpace(roles)) {                this.Roles = roles.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);            }            base.OnAuthorization(filterContext);        }    }

 

当用户请求一个Action时,会调用OnAuthorization方法,该方法中GetRoles.GetActionRoles(actionName, controllerName);根据Controller和Action去查找当前Action需要具有的角色类型,获得Action的Roles以后,在AuthorizeCore中与用户的角色进行比对Roles.Any(httpContext.User.IsInRole),如果没有相应权限则返回false,程序就会自动跳转到登录页面。

 

GetRoles为XML解析类,代码如下:

 
public class GetRoles    {               public static string GetActionRoles(string action, string controller) {            XElement rootElement = XElement.Load(HttpContext.Current.Server.MapPath("/")+"ActionRoles.xml");            XElement controllerElement = findElementByAttribute(rootElement, "Controller", controller);            if (controllerElement != null)            {                XElement actionElement = findElementByAttribute(controllerElement, "Action", action);                if (actionElement != null)                {                    return actionElement.Value;                }            }            return "";        }        public static XElement findElementByAttribute(XElement xElement,string tagName, string attribute)        {            return xElement.Elements(tagName).FirstOrDefault(x => x.Attribute("name").Value.Equals(attribute,StringComparison.OrdinalIgnoreCase));        }    }

 

相应的权限XMl文件:

 

Manager,Admin
Admin

 

当需求发生变化时,只需要修改XML文件即可

使用时,只需要在FilterConfig中注册该filter

filters.Add(new CustomAuthorizeAttribute());

 

当然这只是一个简单的例子,实际应用中会复杂许多,还可能要实现在即的MemberShipProvider和RoleProvider

转载地址:http://tmnxa.baihongyu.com/

你可能感兴趣的文章
搭建LAMP架构
查看>>
神经网络注意力机制--Attention in Neural Networks
查看>>
Spring.Net+WCF实现分布式事务
查看>>
在Linux上高效开发的7个建议
查看>>
java数据结构 - 数组使用的代码
查看>>
个人简历-项目经验
查看>>
swoole异步任务task处理慢请求简单实例
查看>>
DHCP
查看>>
oracle数据泵导入分区表统计信息报错(四)
查看>>
spring技术内幕读书笔记之IoC容器的学习
查看>>
细说多线程(五) —— CLR线程池的I/O线程
查看>>
JavaScript instanceof和typeof的区别
查看>>
Hadoop文件系统详解-----(一)
查看>>
《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(8)--- 主动器...
查看>>
状态码
查看>>
我的友情链接
查看>>
用sqlplus远程连接oracle命令
查看>>
多年一直想完善的自由行政审批流程组件【2002年PHP,2008年.NET,2010年完善数据设计、代码实现】...
查看>>
自动生成四则运算题目
查看>>
【翻译】使用新的Sencha Cmd 4命令app watch
查看>>