Web APi之过滤器执行过程原理解析【二】(十一)

简介:

前言

上一节我们详细讲解了过滤器的创建过程以及粗略的介绍了五种过滤器,用此五种过滤器对实现对执行Action方法各个时期的拦截非常重要。这一节我们简单将讲述在Action方法上、控制器上、全局上以及授权上的自定义特性的执行过程。

APiController 

之前有讲到该APiController,也就稍微介绍了,这节我们来详细此Web API控制器的基类:

复制代码
 1 public abstract class ApiController : IHttpController, IDisposable
 2 {
 3     // Fields
 4     private HttpConfiguration _configuration;
 5     private HttpControllerContext _controllerContext;
 6     private bool _disposed;
 7     private ModelStateDictionary _modelState;
 8     private HttpRequestMessage _request;
 9     private UrlHelper _urlHelper;
10 
11     // Methods
12     protected ApiController();
13     public void Dispose();
14     protected virtual void Dispose(bool disposing);
15     public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken);
16     protected virtual void Initialize(HttpControllerContext controllerContext);
17     internal static Func<Task<HttpResponseMessage>> InvokeActionWithActionFilters(HttpActionContext actionContext, CancellationToken cancellationToken, IEnumerable<IActionFilter> filters, Func<Task<HttpResponseMessage>> innerAction);
18     internal static Func<Task<HttpResponseMessage>> InvokeActionWithAuthorizationFilters(HttpActionContext actionContext, CancellationToken cancellationToken, IEnumerable<IAuthorizationFilter> filters, Func<Task<HttpResponseMessage>> innerAction);
19     internal static Task<HttpResponseMessage> InvokeActionWithExceptionFilters(Task<HttpResponseMessage> actionTask, HttpActionContext actionContext, CancellationToken cancellationToken, IEnumerable<IExceptionFilter> filters);
20 
21     // Properties
22     public HttpConfiguration Configuration { get; set; }
23     public HttpControllerContext ControllerContext { get; set; }
24     public ModelStateDictionary ModelState { get; }
25     public HttpRequestMessage Request { get; set; }
26     public UrlHelper Url { get; set; }
27     public IPrincipal User { get; }
28 
29     // Nested Types
30     private class FilterGrouping
31     {
32         // Fields
33         private List<IActionFilter> _actionFilters;
34         private List<IAuthorizationFilter> _authorizationFilters;
35         private List<IExceptionFilter> _exceptionFilters;
36 
37         // Methods
38         public FilterGrouping(IEnumerable<FilterInfo> filters);
39         private static void Categorize<T>(IFilter filter, List<T> list) where T: class;
40 
41         // Properties
42         public IEnumerable<IActionFilter> ActionFilters { get; }
43         public IEnumerable<IAuthorizationFilter> AuthorizationFilters { get; }
44         public IEnumerable<IExceptionFilter> ExceptionFilters { get; }
45     }
46 }
复制代码

我们首先来看看此类中的一个私有类 FilterGrouping ,顾名思义是对过滤器分组,我们查看其构造函数看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
public  FilterGrouping(IEnumerable<FilterInfo> filters)
{
     this ._actionFilters =  new  List<IActionFilter>();
     this ._authorizationFilters =  new  List<IAuthorizationFilter>();
     this ._exceptionFilters =  new  List<IExceptionFilter>();
     foreach  (FilterInfo info  in  filters)
     {
         IFilter instance = info.Instance;
         Categorize<IActionFilter>(instance,  this ._actionFilters);
         Categorize<IAuthorizationFilter>(instance,  this ._authorizationFilters);
         Categorize<IExceptionFilter>(instance,  this ._exceptionFilters);
     }
}

我们仅仅只需 _actionFilters 为例,其余一样,我们再来看看 Categorize 方法:

复制代码
1 private static void Categorize<T>(IFilter filter, List<T> list) where T: class
2 {
3     T item = filter as T;
4     if (item != null)
5     {
6         list.Add(item);
7     }
8 }
复制代码

从这里我们可以得知:

当我们在HttpActionDescriptor初始化创建了封装了Filter对象的FilterInfo的集合列表,此时然后利用此类中的三个属性类型:IActionFilter、IAuthorizationFilter、以及IExceptionFilter进行过滤器分组得到对应过滤器集合列表

执行过程原理解析 

下面我们通过例子来看看之执行过程,我们自定义以下五个过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/// <summary>
    /// 全局的行为过滤器
    /// </summary>
    public  class  CustomConfigurationActionFilterAttribute : FilterAttribute, IActionFilter
    {
        public  Task<HttpResponseMessage> ExecuteActionFilterAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }
 
    /// <summary>
    /// 控制器级行为过滤器
    /// </summary>
    public  class  CustomControllerActionFilterAttribute : FilterAttribute, IActionFilter
    {
        public  Task<HttpResponseMessage> ExecuteActionFilterAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }
 
    /// <summary>
    /// 控制器方法级行为过滤器
    /// </summary>
    public  class  CustomActionFilterAttribute : FilterAttribute, IActionFilter
    {
        public  Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }
 
    /// <summary>
    /// 控制器级授权访问过滤器
    /// </summary>
    public  class  CustomControllerAuthorizationFilterAttribute : FilterAttribute, IAuthorizationFilter
    {
        public  Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }
 
    /// <summary>
    /// 控制器方法级授权访问过滤器
    /// </summary>
    public  class  CustomControllerActionAuthorizationFilterAttribute : FilterAttribute, IAuthorizationFilter
    {
        public  Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }

接下来就是实现过滤器,配置文件中配置全局过滤器

1
config.Filters.Add( new  CustomConfigurationActionFilterAttribute());

控制器及方法上过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[CustomControllerAuthorizationFilter]
[CustomControllerActionFilter]
public  class  ProductController : ApiController
{
     [CustomActionFilter]
     [CustomControllerActionAuthorizationFilter]
     public  string  GetFilter()
     {
         var  sb =  new  StringBuilder();
 
         var  actionSelector =  this .Configuration.Services.GetActionSelector();
         var  actionDesciptor = actionSelector.SelectAction( this .ControllerContext);
         foreach  ( var  filterInfo  in  actionDesciptor.GetFilterPipeline())
         {
             sb.AppendLine( "【FilterName:"  + filterInfo.Instance.GetType().Name +  ",FilterScope:"  + filterInfo.Scope.ToString() +  "】" );
         }
         return  sb.ToString();
     }
}

最后来查看其结果:

看到这里是不是有点疑惑怎么按照Global->Controller->Action来进行排序,如果你看过前面文章就会知道这是过滤器管道按照FilterScope来生成的,实际上在服务器端生成的顺序为 CustomControllerAuthorizationFilterAttribute 、 CustomControllerActionAuthorizationFilterAttribute 、 CustomConfigurationActionFilterAttribute 、 CustomControllerActionFilterAttribute 以及 CustomActionFilterAttribute 由此我们得出结论:

授权过滤器不管任何的FilterScope都是优于行为过滤器,而在同一种类型的过滤器中是根据FilterScope来确定执行顺序的。 

总结 

有关更多深入的内容就不再探讨,本想多写一点,但是状态不佳加上更多内容比较复杂以免说不太明白云里雾里,想想还是算了,就这样了,下面还是给出其一张执行的详细示意图,来源【过滤器执行过程

  

接下来将通过实例详细讲解Web API中的认证(Authentication)以及授权(Authorization),敬请期待。。。。。。











本文转自Jeffcky博客园博客,原文链接:http://www.cnblogs.com/CreateMyself/p/4855419.html,如需转载请自行联系原作者

目录
相关文章
|
5月前
|
缓存 安全 Java
《深入理解Spring》过滤器(Filter)——Web请求的第一道防线
Servlet过滤器是Java Web核心组件,可在请求进入容器时进行预处理与响应后处理,适用于日志、认证、安全、跨域等全局性功能,具有比Spring拦截器更早的执行时机和更广的覆盖范围。
|
10月前
|
存储 算法 安全
JWT深度解析:现代Web身份验证的通行证为什么现在都是JWT为什么要restful-优雅草卓伊凡
JWT深度解析:现代Web身份验证的通行证为什么现在都是JWT为什么要restful-优雅草卓伊凡
532 41
JWT深度解析:现代Web身份验证的通行证为什么现在都是JWT为什么要restful-优雅草卓伊凡
|
10月前
|
存储 应用服务中间件 nginx
在使用Nginx之后,如何在web应用中获取用户IP以及相关原理
但总的来说,通过理解网络通信的基础知识,了解http协议以及nginx的工作方式,我们已经能在大多数情况下准确地获取用户的真实IP地址了,在调试问题或者记录日志时会起到很大的帮助。
558 37
|
机器学习/深度学习 数据可视化 PyTorch
深入解析图神经网络注意力机制:数学原理与可视化实现
本文深入解析了图神经网络(GNNs)中自注意力机制的内部运作原理,通过可视化和数学推导揭示其工作机制。文章采用“位置-转移图”概念框架,并使用NumPy实现代码示例,逐步拆解自注意力层的计算过程。文中详细展示了从节点特征矩阵、邻接矩阵到生成注意力权重的具体步骤,并通过四个类(GAL1至GAL4)模拟了整个计算流程。最终,结合实际PyTorch Geometric库中的代码,对比分析了核心逻辑,为理解GNN自注意力机制提供了清晰的学习路径。
769 7
深入解析图神经网络注意力机制:数学原理与可视化实现
|
11月前
|
人工智能 搜索推荐 IDE
突破网页数据集获取难题:Web Unlocker API 助力 AI 训练与微调数据集全方位解决方案
本文介绍了Web Unlocker API、Web-Scraper和SERP API三大工具,助力解决AI训练与微调数据集获取难题。Web Unlocker API通过智能代理和CAPTCHA绕过技术,高效解锁高防护网站数据;Web-Scraper支持动态内容加载,精准抓取复杂网页信息;SERP API专注搜索引擎结果页数据抓取,适用于SEO分析与市场研究。这些工具大幅降低数据获取成本,提供合规保障,特别适合中小企业使用。粉丝专属体验入口提供2刀额度,助您轻松上手!
557 2
|
11月前
|
人工智能 运维 安全
网络安全公司推荐:F5荣膺IDC全球Web应用与API防护领导者
网络安全公司推荐:F5荣膺IDC全球Web应用与API防护领导者
326 4
|
12月前
|
XML JSON API
Understanding RESTful API and Web Services: Key Differences and Use Cases
在现代软件开发中,RESTful API和Web服务均用于实现系统间通信,但各有特点。RESTful API遵循REST原则,主要使用HTTP/HTTPS协议,数据格式多为JSON或XML,适用于无状态通信;而Web服务包括SOAP和REST,常用于基于网络的API,采用标准化方法如WSDL或OpenAPI。理解两者区别有助于选择适合应用需求的解决方案,构建高效、可扩展的应用程序。
|
12月前
|
传感器 人工智能 监控
反向寻车系统怎么做?基本原理与系统组成解析
本文通过反向寻车系统的核心组成部分与技术分析,阐述反向寻车系统的工作原理,适用于适用于商场停车场、医院停车场及火车站停车场等。如需获取智慧停车场反向寻车技术方案前往文章最下方获取,如有项目合作及技术交流欢迎私信作者。
923 2
|
12月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
5月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
469 4

推荐镜像

更多
  • DNS