MVC 自定义AuthorizeAttribute实现权限管理

来源:互联网 发布:机顶盒桌面软件 编辑:程序博客网 时间:2024/04/29 21:02

MVC中AuthorizeAttribute用法并实现授权管理

(2015-01-05 13:49:30)
转载
标签:

authorizeattribute

handleunauthorized

authorizecore

分类: MVC

 MVC中AuthorizeAttribute用法并实现授权管理

 

1.创建一个类(用来检查用户是否登录和用户权限)代码如下:

    public class MemberCheckAttribute : AuthorizeAttribute
    {

        //AuthorizeAttribute的OnAuthorization方法内部调用了AuthorizeCore方法,这个方法是实现验证和授权逻辑的地方,如果这个方法返回true,表示授权成功,如果返回false,表示授权失败, 会给上下文设置一个HttpUnauthorizedResult,这个ActionResult执行的结果是向浏览器返回一个401状态码,但是返回状态码没什么意思,通常是跳转到一个登录页面,可以重写AuthorizeAttribute的HandleUnauthorizedRequest跳转到相应的页面
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            base.AuthorizeCore(httpContext);
            if (true)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //如果AuthorizeCore返回false才会执行HandleUnauthorizedRequest

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            base.HandleUnauthorizedRequest(filterContext);
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            else
            {
                filterContext.HttpContext.Response.Redirect("/login.html");
            }
        }
    }

2.页面程序,也就是控制器里的程序,如下

//MemberCheck是扩展特性,自定义特性名称是根据上面的类MemberCheckAttribute名进行变化

//当访问/user/index时,程序会先走自定义特性MemberCheck然后再走Index

[MemberCheck]
public class UserController : Controller
{

       public ActionResult Index()
        {
            return View();
        }

}



MVC 自定义AuthorizeAttribute实现权限管理

在上一节中提到可以使用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文件:

 

复制代码
<?xml version="1.0" encoding="utf-8" ?><Roles>    <Controller name="Home">        <Action name="Index"></Action>        <Action name="About">Manager,Admin</Action>        <Action name="Contact">Admin</Action>    </Controller></Roles>
复制代码

 

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

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

filters.Add(new CustomAuthorizeAttribute());

 

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

 

 

 

分类: C#
好文要顶 关注我 收藏该文
Johnny Yan
关注 - 15
粉丝 - 114
+加关注
11
1
«上一篇:MVC Action Filter
»下一篇:MVC Area领域处理以及T4MVC的使用
posted @ 2012-07-24 15:54 Johnny Yan 阅读(28421) 评论(7)编辑 收藏

  
#1楼2012-09-25 09:48 s_p  
楼主 当自定义的时候 新建一个类A继承于AuthorizeAttribute
重写 AuthorizeCore OnAuthorization 后我在我用验证权限的类继承类A
我要启用权限在上面加
[Authorize(Roles=???)] 这个怎么写啊 !
还有新建一个类的时候CustomAuthorizeAttribute 我看网上的都加了这个后缀Attribute 不加不行吗 也没看到为什么的原因 呵呵!
支持(0)反对(0)
http://pic.cnblogs.com/face/331132/20150709142727.png
  
#2楼2013-06-15 08:51 Moon.Orm塑造Orm经典  
使用时,只需要在Global.asax中注册该filter

filters.Add(new CustomAuthorizeAttribute());

================
楼主这个在哪里注册的?
支持(0)反对(0)
http://pic.cnblogs.com/face/83201/20130712091921.png
  
#3楼2013-10-10 14:06 C#学习路  
@ Moon.NET极速开发框架

这个我也没找到方法,但可以在要使用的Controller里引用一下“CustomAuthorizeAttribute ”的命名空间也行;
支持(0)反对(0)
  
#4楼2013-10-10 14:10 C#学习路  
使用时,只需要在Global.asax中注册该filter

filters.Add(new CustomAuthorizeAttribute());


请问楼主怎么实现?
支持(0)反对(0)
  
#5楼2013-10-14 10:06 sportdog  
把这个[CustomAuthorizeAttribute ]加到你的actionresult或controller上都可以了.
支持(0)反对(0)
  
#6楼2015-04-02 00:17 dota3c  
感谢楼主,有学到新知识了
支持(0)反对(0)
  
#7楼33093502015/11/18 17:10:25 2015-11-18 17:10 njl_041x  
文章不错,实用,支持一下~~~
支持(0)反对(0)

0 0
原创粉丝点击