zoukankan      html  css  js  c++  java
  • mvc过滤器学习(1)

    mvc 过滤器结构图

    AuthorizeAttribute

    AuthorizeAttribute是IAuthorizationFilter的默认实现,添加了Authorize特性的Action将对用户进行验证授权,只有通过了用户才可以进入这个Action.

    AuthorizeAttribute提供了四种操作方法,打开.net reflector查看源码

    1.在进入Action之前首先执行OnAuthorization

            public virtual void OnAuthorization(AuthorizationContext filterContext)
            {
                if (filterContext == null)
                {
                    throw new ArgumentNullException("filterContext");
                }
                if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
                {
                    throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
                }
                if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
                {
                    if (this.AuthorizeCore(filterContext.HttpContext))
                    {
                        HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
                        cache.SetProxyMaxAge(new TimeSpan(0L));
                        cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null);
                    }
                    else
                    {
                        this.HandleUnauthorizedRequest(filterContext);
                    }
                }
            }

    2.在OnAuthorization内部会调用AuthorizeCore

     protected virtual bool AuthorizeCore(HttpContextBase httpContext)
            {
                if (httpContext == null)
                {
                    throw new ArgumentNullException("httpContext");
                }
                IPrincipal user = httpContext.User;
                if (!user.Identity.IsAuthenticated)
                {
                    return false;
                }
                if ((this._usersSplit.Length > 0) && !this._usersSplit.Contains<string>(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
                {
                    return false;
                }
                if ((this._rolesSplit.Length > 0) && !this._rolesSplit.Any<string>(new Func<string, bool>(user.IsInRole)))
                {
                    return false;
                }
                return true;
            }

    默认实现,不仅判断是否授权,还可以具体到某一个角色,某一个用户,但这些角色是哪里来的呢?

    (1)使用membership框架

    (2)使用微软最新的Identity框架

    (3)自定义一个类继承RoleProvider,并设置配置文件

        <roleManager>
          <providers>
            <clear/>
            <add name="MyRoleProvider" type="Filter.Controllers.MyRoleProvider" />
          </providers>
        </roleManager>

    3.AuthorizeCore返回一个布尔值,表示是否通过授权,未通过将执行HandUnauthorizedRequest返回配置文件forms-loginUrl指向的页面

            protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
            {
                filterContext.Result = new HttpUnauthorizedResult();
            }

    4.OnAuthorization在缓存模块请求授权时调用

            protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
            {
                if (httpContext == null)
                {
                    throw new ArgumentNullException("httpContext");
                }
                if (!this.AuthorizeCore(httpContext))
                {
                    return HttpValidationStatus.IgnoreThisRequest;
                }
                return HttpValidationStatus.Valid;
            }

    ActionFilterAttribute

    ActionFilterAttribute在mvc中没有默认实现,需要自己定义

    1.OnActionExecuting在OnAuthorization之后(实际上ActionFilter中的方法都在其之后)进入Action之前执行

    2.OnActionExecuted在Action中所有语句都执行完之后执行

    3.OnResultExecuting在执行操作结果(返回继承自ActionResult的所有类型)前调用

    4.OnResultExecuted在执行操作结果(返回继承自ActionResult的所有类型)后调用

     public class MyActionFilterAttribute : ActionFilterAttribute
        {
            /// <summary>
            /// 在执行操作方法之前由 ASP.NET MVC 框架调用。
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
           
            }
            /// <summary>
            /// 在执行操作方法后由 ASP.NET MVC 框架调用。
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
    
            }
            /// <summary>
            /// 在执行操作结果之前由 ASP.NET MVC 框架调用。
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
         
            }
            /// <summary>
            /// 在执行操作结果后由 ASP.NET MVC 框架调用。
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
    
            }
    
        }

    HandleErrorAttribute

    HandleErrorAttribute是IException的默认实现,在调式的时候,出现异常就会蹦出那黄色的页面

    我们也可以自定义异常处理

    需要注意的是ExceptionHandled表示这个异常是否已经处理(可能程序中有多个异常过滤器)

        public class MyExceptionAttribute : HandleErrorAttribute
        {
            public override void OnException(ExceptionContext filterContext)
            {
                if (!filterContext.ExceptionHandled)//避免重复处理
                {
                    //获取抛出异常的对象  
                    Exception ex = filterContext.Exception;
                    //写入异常日志
    
                    //已处理 
                    filterContext.ExceptionHandled = false;
                }
            }
        }

    IAuthenticationFilter

    IAuthenticationFilter是认证过滤器接口,他提供了两个操作方法

    1.OnAuthentication在所有过滤器执行前执行(包括授权过滤器)

    2.OnAuthenticationChallenge在OnResultExecuting前执行

    小结

    过滤器是把附加逻辑注入到MVC框架的请求处理.它们提供一种简单而雅致的方式,实现了交叉关注,所谓交叉关注,是指可以用于整个应用程序,二用不适合放置在某个局部位置的功能,否则就会打破关注分离模式.典型的交叉关注例子就是登陆,授权以及缓存等.(摘自精通asp.net mvc5)

  • 相关阅读:
    ORA-14404
    ORA-00845
    ORA-00054
    oracle-11g-配置dataguard
    ORACLE 11G 配置DG 报ORA-10458、ORA-01152、ORA-01110
    Python:if __name__ == '__main__'
    HDFS-Shell 文件操作
    HDFS 概述
    PL/SQL Developer
    CentOS7 图形化方式安装 Oracle 18c 单实例
  • 原文地址:https://www.cnblogs.com/cheesebar/p/6004064.html
Copyright © 2011-2022 走看看