.NET MVC5 Introduction (four) Filter AuthorizeAttribute rights and verification

In webform, the verification process is as follows:

 

 

 In AOP:

 

 

 In the Filter:

 

 

AuthorizeAttribute permission verification 

After logging have access control, and some pages that require the user to log in to access, you need to add a verification visit the page, you can not have every action again.

1, write a CustomAuthorAttribute, inherited from AuthorizeAttribute, rewrite OnAuthorization method, in which the logic written in his own.

2, there are ways to register and control register.

3, global registration, all controllers all action takes effect.

But in the inside, we must first verify login Home Home no liability and went to the login page, login page but also to go inside the characteristics of logic, and redirected to Teresa. . . The cycle. . . .

There is a AlloAnonymous, the label can solve the problem of this cycle, anonymous support, do not need to log on it, but only of Stuttgart is of no use, in fact, support authentication is required, or even your own custom feature is also a possible this feature is empty inside, only to be used to make mark.

Characteristic range, desirable characteristics of general-purpose, different systems, different address registration, == "characteristic above plus a constructor parameter passing.

 public class CustomAllowAnonymousAttribute : Attribute
 {
 }

CustomAuthorAttribute类

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    private Logger logger = new Logger(typeof(CustomAuthorizeAttribute));
    private string _LoginUrl = null;
    public CustomAuthorizeAttribute(string loginUrl = "~/Home/Login")
    {
        this._LoginUrl = loginUrl;
    }
    //public CustomAuthorizeAttribute(ICompanyUserService service)
    //{
    //}
    //不行


    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var httpContext = filterContext.HttpContext;//能拿到httpcontext 就可以为所欲为

        if (filterContext.ActionDescriptor.IsDefined(typeof(CustomAllowAnonymousAttribute), true))
        {
            return;
        }
        else if (filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(CustomAllowAnonymousAttribute), true))
        {
            return;
        }
        the else  if (httpContext.Session [ " the CurrentUser " ] == null 
            ||! (httpContext.Session [ " the CurrentUser " ] IS the CurrentUser)) // is empty, 
        {
             // Here the user, the address can actually check permissions 
            if (httpContext.Request.IsAjaxRequest ())
                 // httpContext.Request.Headers [ "XXX"]. Equals ( "XMLHttpRequst") 
            { 
                filterContext.Result = new new NewtonJsonResult (
                     new new AjaxResult () 
                    {
                        The Result  =DoResult.OverTime, 
                        DebugMessage = " login expired " , 
                        retValue = "" 
                    }); 
            } 
            the else 
            { 
                httpContext.Session [ " CURRENTURL " ] = httpContext.Request.Url.AbsoluteUri; 
                filterContext.Result = new new RedirectResult ( the this ._LoginUrl) ;
                 // crowbar: the Result is specified, then the request is turned off, and does not perform Action 
            } 
        } 
        the else 
        {
            User the CurrentUser = (the CurrentUser) httpContext.Session [ " the CurrentUser " ];
             // this.logger.Info ($ "} {user.name landing system"); 
            return ; // continue 
        }
         // base.OnAuthorization (filterContext) ; 
    } 
}

Filter into force mechanism

Why add a label, inheritance AuthorizeAttribute, rewrite OnAuthorization method can it? The controller has been instantiated, calling ExecuteCore method, find a way to name, ControllerActionInvokee.InvokeAction, find all Filter characteristics, InvokeAuthorize - result is not empty directly InvokeActionResult, empty on the implementation of Action to normal.

One instance type, there is a method name, you want to perform reflection

After finding method, before performing the method, the characteristic may be detected from the overall, from the controller, from the method. Spread characteristics, the characteristics of their own predefined by class execution, will be a logo, it is normal for the empty, not empty jumps, normal execution continues.

Filter principle and AOP Aspect Oriented Programming

Filter AOP is an implementation idea, in fact, ControllerActionInvoke this class, there is a method InvokeAction, after the controller is instantiated, the front and rear ActionInvoke, by detecting a predefined Filter and executes it, the purpose of the AOP.

Here is InvokeAction source:

public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (string.IsNullOrEmpty(actionName) && !controllerContext.RouteData.HasDirectRouteMatch())
            {
                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
            }
            ControllerDescriptor controllerDescriptor = this.GetControllerDescriptor(controllerContext);
            ActionDescriptor actionDescriptor = this.FindAction(controllerContext, controllerDescriptor, actionName);
            if (actionDescriptor != null)
            {
                FilterInfo filters = this.GetFilters(controllerContext, actionDescriptor);
                try
                {
                    AuthenticationContext authenticationContext = this.InvokeAuthenticationFilters(controllerContext, filters.AuthenticationFilters, actionDescriptor);
                    if (authenticationContext.Result != null)
                    {
                        AuthenticationChallengeContext authenticationChallengeContext = this.InvokeAuthenticationFiltersChallenge(controllerContext, filters.AuthenticationFilters, actionDescriptor, authenticationContext.Result);
                        this.InvokeActionResult(controllerContext, authenticationChallengeContext.Result ?? authenticationContext.Result);
                    }
                    else
                    {
                        AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor);
                        if (authorizationContext.Result != null)
                        {
                            AuthenticationChallengeContext authenticationChallengeContext2 = this.InvokeAuthenticationFiltersChallenge(controllerContext, filters.AuthenticationFilters, actionDescriptor, authorizationContext.Result);
                            this.InvokeActionResult(controllerContext, authenticationChallengeContext2.Result ?? authorizationContext.Result);
                        }
                        else
                        {
                            if (controllerContext.Controller.ValidateRequest)
                            {
                                ControllerActionInvoker.ValidateRequest(controllerContext);
                            }
                            IDictionary<string, object> parameterValues = this.GetParameterValues(controllerContext, actionDescriptor);
                            ActionExecutedContext actionExecutedContext = this.InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, actionDescriptor, parameterValues);
                            AuthenticationChallengeContext authenticationChallengeContext3 = this.InvokeAuthenticationFiltersChallenge(controllerContext, filters.AuthenticationFilters, actionDescriptor, actionExecutedContext.Result);
                            this.InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, authenticationChallengeContext3.Result ?? actionExecutedContext.Result);
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                catch (Exception exception)
                {
                    ExceptionContext exceptionContext = this.InvokeExceptionFilters(controllerContext, filters.ExceptionFilters, exception);
                    if (!exceptionContext.ExceptionHandled)
                    {
                        throw;
                    }
                    this.InvokeActionResult(controllerContext, exceptionContext.Result);
                }
                return true;
            }
            return false;
        }
View Code

Global exception handler HandleErrorAttribute

Recommendations on exception handling:

  1, to avoid the UI layer directly see an exception, each controller inside try-catch it? Not very trouble?

  2, this time, AOP on debut, HandleErrorAttribute, wrote a feature of succession HandleErrorAttribute, rewrite OnException, after an exception occurs, will jump to this method.

Here, we must

 public  class CustomHandleErrorAttribute: HandleErrorAttribute 
 { 
     Private Logger Logger = new new Logger ( typeof (CustomHandleErrorAttribute)); 

     ///  <Summary> 
     /// will exception occurs, the method jumps to
      ///  </ Summary> 
     ///  < name = param "filterContext"> </ param> 
     public  the override  void the OnException (ExceptionContext filterContext) 
     { 
         var httpContext = filterContext.HttpContext; // "pleases" 
         IF (filterContext.ExceptionHandled!) // not deal with other HandleErrorAttribute 
         {
             this.logger.Error($"在响应 {httpContext.Request.Url.AbsoluteUri} 时出现异常,信息:{filterContext.Exception.Message}");//
             if (httpContext.Request.IsAjaxRequest())
             {
                 filterContext.Result = new NewtonJsonResult(
                 new AjaxResult()
                 {
                     Result = DoResult.Failed,
                     DebugMessage = filterContext.Exception.Message,
                     RetValue = "",
                     PromptMsg = "Error, please contact the administrator " 
                 }); 
             } 
             the else 
             { 
                 filterContext.Result = new new a ViewResult () // crowbar 
                 { 
                     ViewName = " ~ / the Views / the Shared / Error.cshtml " , 
                     the ViewData = new new the ViewDataDictionary < String > (filterContext .Exception.Message) 
                 }; 
             } 
             filterContext.ExceptionHandled = to true ; // I have been dealt with
         }
     }
 }

This is to re-jump address:

 

 

 Be sure to take into account is not the Ajax request

 

 

 

 

 

 A variety of unusual circumstances, can not enter the abnormal customize it?

1, Action abnormal, not Catch

2, Action abnormal, is Catch

3, Action call aberrant Service

4, abnormal Action appeared normal view

5 abnormal, the controller configured to appear

6, Action Name Error

7, any wrong address

8, abnormal permission Filter

answer:

1, can

2, can not

3, abnormal bubble

4, can be, and why? Because ExecuteResult is wrapped in a try inside

5, not possible, Filter is completed prior to completion of the control method is performed after construction

6, not because the request did not flow into the MVC

7, not possible because the request did not enter MVC

8, can, powers Filter also in the try inside.

That these are not caught exceptions how to do? There is a way

Add an event in the Global

 public  class MvcApplication: System.Web.HttpApplication 
 { 
     Private Logger Logger = new new Logger ( typeof (MvcApplication));
      protected  void the Application_Start () 
     { 
         AreaRegistration.RegisterAllAreas (); // registration area 
         FilterConfig.RegisterGlobalFilters (GlobalFilters.Filters); // Sign overall the Filter 
         RouteConfig.RegisterRoutes (RouteTable.Routes); // Register route 
         BundleConfig.RegisterBundles (BundleTable.Bundles); // merger compression, packaging tools Combres 
         ControllerBuilder.Current.SetControllerFactory (new new ElevenControllerFactory ()); 

         the this .logger.Info ( " website launched ... " ); 
     } 
     ///  <the Summary> 
     /// exception handling global type, you can catch slip through
      ///  </ the Summary > 
     ///  <param name = "SENDER"> </ param> 
     ///  <param name = "E"> </ param> 
     protected  void the Application_Error ( Object SENDER, EventArgs E) 
     { 
         Exception EXCETION = the Server.GetLastError () ;
          the this .logger.Error ($ " {} base.Context.Request.Url.AbsoluteUri abnormal " );
         Response.Write("System is Error....");
         Server.ClearError();

         //Response.Redirect
         //base.Context.RewritePath("/Home/Error?msg=")
     }

HandleErrorAttribute + Application_Error, size is not the same, you will get something different

IActionFilter custom extensions

IActionFilter

Before 1, OnActionExecuting execution method

2, the method of performing OnActionExecuted

3, before the result of the implementation of OnResultExecuting

4, after the results of the implementation of OnResultExecuted

First execute permissions Filter, and then execute ActionFilter.

The order of execution:

  Global OnActionExecuting

  Controller OnActionExecuting

  Action OnActionExecuting

  Action actual execution

  Action OnActionExecuted

  Controller OnActionExecuted

  Global OnActionExecuted

 

 

Entry into force of the order of registration of different locations: Global --- "Controller -----" Action

Like a Russian doll, or onion model

 

 

In order to take effect the same location registration, the same position in the order to take effect, there is an Order of the parameter, the default is not set Order 1, after setting ascending execution

 

 

 

ActionFilter can you do?

Log parameter detection, cache, rewrite view, compression, security chain, access to statistics, different clients to jump to different pages, current limiting .....

When a browser requests, will declare their support for the format, the default IIS is not compressed, it examined the supported formats, in response to the data compression (IIS server to complete), in response to head inside with Content-Encoding, browser View data format, decompression (no matter what you are, you can compress decompressed) in accordance with the browser format, compression is IIS, decompression is the browser.

 public  class CompressActionFilterAttribute: the ActionFilterAttribute 
 { 
     public  the override  void the OnActionExecuting (ActionExecutingContext filterContext) 
     { 
         // the foreach (var Item in filterContext.ActionParameters)
          // {
          //     // parameter detector sensitive word filtering
          // }   
         var Request = filterContext.HttpContext.Request;
          var Respose = filterContext.HttpContext.Response;
          String acceptEncoding Request.Headers = [ " the Accept-Encoding " ]; // detecting supported formats
         if (!string.IsNullOrWhiteSpace(acceptEncoding) && acceptEncoding.ToUpper().Contains("GZIP"))
         {
             respose.AddHeader("Content-Encoding", "gzip");//响应头指定类型
             respose.Filter = new GZipStream(respose.Filter, CompressionMode.Compress);//压缩类型指定
         }
     }
 }

 public class LimitActionFilterAttribute : ActionFilterAttribute
 {
     private int _Max = 0;
     public LimitActionFilterAttribute(int max = 1000)
     {
         this._Max = max;
     }
     public override void OnActionExecuting(ActionExecutingContext filterContext)
     {
         string key = $"{filterContext.RouteData.Values["Controller"]}_{filterContext.RouteData.Values["Action"]}";
         //CacheManager.Add(key,) 存到缓存key 集合 时间  
         filterContext.Result = new JsonResult()
         {
             The Data= New new {Msg = " exceeds the frequency " } 
         }; 
     } 
 }

 

 

 

 

 

 

 Filter so much, is there any limitations? ? ? ?

Although very rich, but only in Action as a unit, internal Action call other libraries, plus operation would not do! This must rely on IOC + AOP extension.

Benpian just introduced the .NET Framework MVC filters in Filter (permissions characteristics, Action, Result, Exception), in fact, .NET Core MVC increased ResourceFilter, the addition of this feature, resource characteristics, Action / Result / Exception three What characteristics did not change. Further detail later when recording to the .NET Core MVC.

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/taotaozhuanyong/p/11575590.html