net core Filter FilterPipeline

1 全局注册 2 ServiceFilter,IOC注册  3 TypeFilter  4  4IFilterFactiory 自定义

 

ServiceFilter  是利用ioc 容器获取实例   

public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
if (serviceProvider == null)
{
throw new ArgumentNullException(nameof(serviceProvider)) ;
var filter = (IFilterMetadata)serviceProvider.GetRequiredService(ServiceType);if (filter is IFilterFactory filterFactory)

filter = filterFactory.CreateInstance(serviceProvider) ;
return filter;
}

 

 

 

 

 

 

typeFilter 是利用反射CreateInstance  创建对象实例 所以在标记特性的类型,serviceFileter 需要配置映射关系,而typeFilter 不需要的

 

 

 

 

2  feilter 每次请求都要实例化吗?  答案 是其实会缓存的 如果某个Filter需要实时创建  只有一个办法 就是filterfactory

 IsReusable  =false  表示 不缓存

 

 

3 IHttpContextAccessor  可以注入到attrubute 获取上下文  而且是线程安全的

 4 逻辑控制某个控制器 不执行action  标记特性里验证是否有那个Allowanonymous 特性

 

源码

public void OnAuthorization(AuthorizationFilterContext context)
        {
            Console.WriteLine($"This is {nameof(CustomAuthorizationFilterAttribute)} .OnAuthorization");

            //throw new Exception("CustomAuthorizationFilter Exception");
            if (context.Filters.Any(item => item is IAllowAnonymousFilter))//Microsoft.AspNetCore.Mvc.Authorization.AllowAnonymousFilter
            {
                return;//匿名特性AllowAnonymousAttribute 会生成Filter
            }
            if (context.ActionDescriptor.EndpointMetadata.Any(item => item is IAllowAnonymous))//鉴权授权的Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute
            {
                return;//匿名就不检测,直接继续  EndpointMetadata 获取mc 的信息
  } string user = context.HttpContext.Request.Query["UserName"]; //var memberValidation = HttpContext.Current.Request.Cookies.Get("CurrentUser");//使用cookie //也可以使用数据库、nosql等介质 //context.HttpContext.GetCurrentUserBySession();//读取用户信息 if (string.IsNullOrEmpty(user))//这里可以根据context.HttpContext.Request.Path判断有没有权限  { if (context.HttpContext.Request.IsAjaxRequest()) { context.Result = new JsonResult(new AjaxResult() { Result = false, StatusCode = 401, Message = "用户未登录", });//断路器  } else { //context.HttpContext.Session.SetString("CurrentUrl", context.HttpContext.Request.Path.Value); context.Result = new RedirectResult("~/Filter/Login"); } } else { Console.WriteLine($"This is {user}访问系统"); //this._logger.LogDebug($"{user} 访问系统");  } }

 

 

 

 

5 每个fileter 都是可以嵌套的  

 

6  断路器   

中断后续流程,走非常规流程,
指定context.Result—就不再继续了---如果有AlwaysRunResultFileter 还会吧AlwaysRunResult 折行。

 

posted @ 2021-10-14 20:55  非著名架构师  阅读(78)  评论(0编辑  收藏  举报