zoukankan      html  css  js  c++  java
  • mvc源码解读(11)mvc四大过滤器之AuthorizationFilter

        在上一篇文章中,在讲完ActionDescriptor这个类之后,我们直接跳过了这一句代码:

       FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);

    直接讲了ParameterDescriptor,现在我们回过头来看GetFilters方法返回一个FilterInfo实例,FilterInfo类里面的有如下成员:

           

    public FilterInfo(IEnumerable<Filter> filters) {

          var filterInstances = filters.Select(f => f.Instance).ToList();

           _actionFilters.AddRange(filterInstances.OfType<IActionFilter>());            

           _authorizationFilters.AddRange(filterInstances.OfType<IAuthorizationFilter>());            

           _exceptionFilters.AddRange(filterInstances.OfType<IExceptionFilter>());            

            _resultFilters.AddRange(filterInstances.OfType<IResultFilter>());        

    }

            public IList<IActionFilter> ActionFilters {get {return _actionFilters;}}

            public IList<IAuthorizationFilter> AuthorizationFilters {get {return _authorizationFilters;}}

            public IList<IExceptionFilter> ExceptionFilters {get {return _exceptionFilters;}}

            public IList<IResultFilter> ResultFilters {get {return _resultFilters;}}

    我们可以看到FilterInfo里面涉及到mvc的四大过滤器:AuthorizationFilter,ExceptionFilter,ActionFilter和ResultFilter。类似于.net平台上的HttpModule对客户端发送过来的请求进行拦截从而达到某一种目的。我们知道在企业级的框架中,业务繁杂,对例如权限处理,异常处理,日志管理等这些非商业的业务,我们需要将它和业务处理抽离出来,一方面为了降低架构的耦合度,一方面可以方便我们的维护。而涉及到这些与业务无关的技术处理,比较流行的就是Aop面向切面编程的思想。Aop的核心思想在于:我引用博客园上张逸的详解http://wayfarer.cnblogs.com/articles/241024.html:"它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

        使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离”。而mvc的过滤器正是实现了Aop的这种“横切“思想。

        我们首先来看AuthorizationFilter授权过滤器,顾名思义就是对系统的权限设计把关。而在mvc中所有的过滤器默认都继承了抽象类FilterAttribute,我们来看看FilterAttribute里面的一个重要成员:

            public int Order {

                    get {return _order;}

                    set {if (value < Filter.DefaultOrder) {throw new ArgumentOutOfRangeException("value", MvcResources.FilterAttribute_OrderOutOfRange);}                

                _order = value;}        

    }

    属性Order用于过滤器的排序顺序,关于详细Order的用处,大家可以参考博客园上的蒋金楠老师的这一篇文章(深入探讨ASP.NET MVC的筛选器):http://www.cnblogs.com/artech/archive/2012/07/02/filter.html。同时AuthorizationFilter还实现了接口IAuthorizationFilter里面的OnAuthorization方法:

     public interface IAuthorizationFilter {
            void OnAuthorization(AuthorizationContext filterContext);
        }

    实现类AuthorizeAttribute既继承了抽象类FilterAttribute又实现了IAuthorizationFilter接口,因此如果我们要自定义一个授权过滤器,我们只要让他继承自AuthorizeAttribute类即可,我们先来看看AuthorizeAttribute类里面的主要成员:

     public string Roles {

               get {return _roles ?? String.Empty;}

               set {_roles = value;_rolesSplit = SplitString(value);}

    }

     public string Users {   

               get {return _users ?? String.Empty;}            

               set {_users = value;_usersSplit = SplitString(value);}        

    }

    protected virtual bool AuthorizeCore(HttpContextBase httpContext)

    public virtual void OnAuthorization(AuthorizationContext filterContext)

    protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
                // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
                filterContext.Result = new HttpUnauthorizedResult();
            }

     internal static string[] SplitString(string original) { if (String.IsNullOrEmpty(original)) {return new string[0];}

                var split = from piece in original.Split(',')         

                                let trimmed = piece.Trim() 

                                where !String.IsNullOrEmpty(trimmed)                        

                                select trimmed;            

                return split.ToArray();        

    }

    里面包含用户Users和角色Roles属性,AuthorizeCore方法用来实现授权检查,HandleUnauthorizedRequest方法是当授权失败时处理的动作,HandleUnauthorizedRequest定义如下:

    public class HttpUnauthorizedResult : HttpStatusCodeResult {

            // HTTP 401 is the status code for unauthorized access. Other code might        

           // intercept this and perform some special logic. For example, the        

           // FormsAuthenticationModule looks for 401 responses and instead redirects        

           // the user to the login page.         private const int UnauthorizedCode = 401;

            public HttpUnauthorizedResult(): this(null) {}

            public HttpUnauthorizedResult(string statusDescription) : base(UnauthorizedCode, statusDescription) {}}

    授权失败之后默认是重定向到登录界面,如上英文所示。

         我们前面也讲过了要实现自定义的授权方式,只要继承AuthorizeAttribute类并重写里面AuthorizeCore方法即可。

    protected virtual bool AuthorizeCore(HttpContextBase httpContext) {            

                IPrincipal user = httpContext.User;            

                if (!user.Identity.IsAuthenticated) {

                       return false;

                 }

                if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) {

                       return false;

                  }

                if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) {

                       return false;

                 }

                    return true;        

    }

     因此我们在Controller中的授权如下:

     [Authorization(Roles="admin",Users = "linghuchong")]
            public ActionResult IsLogin()
            {
                return View();
            }

    在Action中贴上Authorization标签之后,只有角色是“admin”且用户名是“linghuchong”才有权访问,这意味着,除非两个条件都满足,否则将不予授权,并会执行HandleUnauthorizedRequest方法。

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    《EffectiveJava中文第二版》 高清PDF下载
    《MoreEffectiveC++中文版》 pdf 下载
    《啊哈c语言》 高清 PDF 下载
  • 原文地址:https://www.cnblogs.com/ghhlyy/p/2917997.html
Copyright © 2011-2022 走看看