端點路由(Endpoint Routing)最先出如今ASP.NET Core2.2,在ASP.NET Core3.0提高爲一等公民。Endpoint Routing的動機git
在端點路由出現以前,咱們通常在請求處理管道的末尾,定義MVC中間件解析路由。這種方式意味着在處理管道中,MVC中間件以前的中間件將沒法得到路由信息。github
路由信息對於某些中間件很是有用,好比CORS、認證中間件(認證過程可能會用到路由信息)。web
同時端點路由提煉出端點
概念,解耦路由匹配邏輯、請求分發。docker
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,並有能力附加處理邏輯;
UseEndpoints是一個終點中間件;
沒有匹配,則進入UseEndpoints以後的中間件。併發
放置在UseRouting
、UseEndpoints
之間的認證受權中間件能夠:
感知被匹配的端點信息;在調度到Endpoint以前,應用受權策略。app
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
定義了健康檢查,該端點定義了IAuthorizeData
metadata,要求先認證再執行健康檢查。框架
咱們在UseRouting、UseEndpoints之間添加一點測試代碼: 感知端點:async
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有所反應。
因而翻閱GithubAuthorizationMiddleware
3.0源碼:發現請求處理的委託確實關注了Endpoint,並提取了metadata中的IAuthorizeData受權信息。
// ---- 截取自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
接口。
bingo, 猜測獲得源碼驗證。
結論
端點路由:容許ASP.NET Core應用程序在中間件管道的早期肯定要調度的端點, 以便後續中間件可使用該信息來提供當前管道配置沒法提供的功能。
這使ASP.NET Core框架更加靈活,強化端點概念,它使路由匹配、解析功能與端點調度功能脫鉤。
-
https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs
閱讀更多
-
TPL Dataflow組件應對高併發,低延遲要求
-
ASP.NET Core跨平臺技術內幕
-
ASP.NET Core結合Redis實踐消息隊列 -
Quartz.net在集羣環境下部署任務的姿式
-
基於docker-compose的Gitlab CI/CD實踐&排坑指南
本文分享自微信公衆號 - dotNET跨平臺(opendotnet)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。