详解ASP.NET Core端点路由的作用原理

所属分类: 网络编程 / ASP.NET 阅读数: 1310
收藏 0 赞 0 分享

端点路由(Endpoint Routing)最早出现在ASP.NET Core2.2,在ASP.NET Core3.0提升为一等公民。

Endpoint Routing的动机

在端点路由出现之前,我们一般在请求处理管道的末尾,定义MVC中间件解析路由。这种方式意味着在处理管道中,MVC中间件之前的中间件将无法获得路由信息。

路由信息对于某些中间件非常有用,比如CORS、认证中间件(认证过程可能会用到路由信息)。

同时端点路由提炼出端点概念,解耦路由匹配逻辑、请求分发。

Endpoint Routing中间件

由一对中间件组成:

UseRouting 将路由匹配添加到中间件管道。该中间件查看应用程序中定义的端点集合,并根据请求选择最佳匹配。UseEndpoints 将端点执行添加到中间件管道。

MapGet、MapPost等方法将 处理逻辑连接到路由系统;

其他方法将 ASP.NET Core框架特性连接到路由系统。

  • MapRazorPages for Razor Pages
  • MapControllers for controllers
  • MapHub< THub> for SignalR
  • MapGrpcService< TService> for gRPC

处于这对中间件上游的 中间件: 始终无法感知 Endpoint;
处于这对中间件之间的 中间件,将会感知到Endpoint,并有能力执行附加处理逻辑;
UseEndpoint是一个终点中间件;
没有匹配,则进入UseEndpoint之后的中间件。


放置在UseRoutingUseEndpoints之间的认证授权中间件可以:
感知被匹配的端点信息;在调度到Endpoint之前,应用授权策略。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  if (env.IsDevelopment())
  {
    app.UseDeveloperExceptionPage();
  }

  // Matches request to an endpoint.
  app.UseRouting();

  // Endpoint aware middleware. 
  // Middleware can use metadata from the matched endpoint.
  app.UseAuthentication();
  app.UseAuthorization();

  // Execute the matched endpoint.
  app.UseEndpoints(endpoints =>
  {
    // Configure the Health Check endpoint and require an authorized user.
    endpoints.MapHealthChecks("/healthz").RequireAuthorization();

    // Configure another endpoint, no authorization requirements.
    endpoints.MapGet("/", async context =>
    {
      await context.Response.WriteAsync("Hello World!");
    });
  });
}

以上在/health定义了健康检查,该端点定义了IAuthorizeDatametadata,要求先认证再执行健康检查。

我们在UseRouting、UseEndpoints之间添加一点口水代码:感知端点:

  app.Use(next => context =>
      {
        var endpoint = context.GetEndpoint();
        if (endpoint is null)
        {
          return Task.CompletedTask;
        }
        Console.WriteLine($"Endpoint: {endpoint.DisplayName}");

        if (endpoint is RouteEndpoint routeEndpoint)
        {
          Console.WriteLine("Endpoint has route pattern: " +
            routeEndpoint.RoutePattern.RawText);
        }

        foreach (var metadata in endpoint.Metadata)
        {
          Console.WriteLine($"Endpoint has metadata: {metadata}");
        }
        return next(context);
      });

当请求/healthz时,感知到AuthorizeAttribute metadata

故猜想认证授权中间件要对/healthz起作用,必然会对这个 AuthorizeAttribute metadata有所反应。

于是翻阅GithubAuthorizationMiddleware3.0源码:发现确实关注了Endpoint

// ---- 截取自https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs-----
if (endpoint != null)
{
  context.Items[AuthorizationMiddlewareInvokedWithEndpointKey] = AuthorizationMiddlewareWithEndpointInvokedValue;
}
var authorizeData = endpoint?.Metadata.GetOrderedMetadata<IAuthorizeData>() ?? Array.Empty<IAuthorizeData>();
var policy = await AuthorizationPolicy.CombineAsync(_policyProvider, authorizeData);
if (policy == null)
{
   await _next(context);
   return;
}
var policyEvaluator = context.RequestServices.GetRequiredService<IPolicyEvaluator>();
......

AuthorizeAttribute确实是实现了IAuthorizeData接口。

binggo, 猜想得到源码验证。

结论

端点路由:允许ASP.NET Core应用程序在中间件管道的早期确定要调度的端点,
以便后续中间件可以使用该信息来提供当前管道配置无法提供的功能。

这使ASP.NET Core框架更加灵活,强化端点概念,它使路由匹配和解析功能与终结点分发功能脱钩。

https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs

更多精彩内容其他人还在看

开源跨平台运行服务插件TaskCore.MainForm

这篇文章主要为大家详细介绍了开源跨平台运行服务插件TaskCore.MainForm的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

CKEditor自定义按钮插入服务端图片

这篇文章主要为大家详细介绍了CKEditor自定义按钮插入服务端图片的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Asp.net Web Api实现图片点击式图片验证码功能

现在验证码的形式越来越丰富,今天要实现的是在点击图片中的文字来进行校验的验证码。下面通过本文给大家分享Asp.net Web Api实现图片点击式图片验证码功能,需要的的朋友参考下吧
收藏 0 赞 0 分享

WPF实现ScrollViewer滚动到指定控件处

这篇文章主要为大家详细介绍了WPF实现ScrollViewer滚动到指定控件处,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

WPF实现带全选复选框的列表控件

这篇文章主要为大家详细介绍了WPF实现带全选复选框的列表控件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Asp.net MVC 中利用jquery datatables 实现数据分页显示功能

这篇文章主要介绍了Asp.net MVC 中利用jquery datatables 实现数据分页显示功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

asp.net 利用NPOI导出Excel通用类的方法

本篇文章主要介绍了asp.net 利用NPOI导出Excel通用类的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

VS2015自带LocalDB数据库用法详解

这篇文章主要为大家详细介绍了VS2015自带LocalDB数据库的用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SignalR Self Host+MVC等多端消息推送服务(一)

这篇文章主要为大家详细介绍了SignalR Self Host+MVC等多端消息推送服务,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

SignalR Self Host+MVC等多端消息推送服务(二)

这篇文章主要为大家详细介绍了SignalR Self Host+MVC等多端消息推送服务的第二篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多