日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

使用 Ocelot 匹配路由的方法匹配路由

發(fā)布時(shí)間:2023/12/4 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 Ocelot 匹配路由的方法匹配路由 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用 Ocelot 匹配路由的方法匹配路由

Intro

之前我們?cè)?Ocelot 網(wǎng)關(guān)的基礎(chǔ)上自定義了一個(gè)認(rèn)證授權(quán)的 Ocelot 中間件,根據(jù)請(qǐng)求的路徑和 Method 進(jìn)行匹配,找到對(duì)應(yīng)的權(quán)限配置,并判斷是否可以擁有訪問(wèn)資源的角色,如果沒(méi)有則返回 401/403,如果有權(quán)限則轉(zhuǎn)發(fā)到下游服務(wù)。

原來(lái)的匹配方式是首先根據(jù)請(qǐng)求路徑和方法完全匹配,如果匹配不到則嘗試使用正則匹配。

我們這次要做的就是將原來(lái)的正則匹配替換成 Ocelot 內(nèi)部的路由匹配方式,這樣我們?cè)谂渲玫臅r(shí)候就不再需要配置兩套了,一邊寫 Ocelot 路由的配置,一邊寫權(quán)限的配置,這樣能減少不少工作量

深入 Ocelot 路由匹配

我們想使用 Ocelot 的路由匹配,首先應(yīng)該了解 Ocelot 的執(zhí)行過(guò)程,然后找到對(duì)應(yīng)的路由匹配的地方,看路由匹配使用到了哪一個(gè)服務(wù),用這個(gè)服務(wù)在我們自己的業(yè)務(wù)邏輯里匹配即可。

先來(lái)看一下 Ocelot 的服務(wù)注冊(cè),Ocelot 的服務(wù)注冊(cè)

可以看到主要的服務(wù)注冊(cè)代碼應(yīng)該在 OcelotBuilder 中,查看 OcelotBuilder https://github.com/ThreeMammals/Ocelot/blob/13.5.2/src/Ocelot/DependencyInjection/OcelotBuilder.cs

可以看到,Ocelot 的服務(wù)注冊(cè)都在這里, Ocelot 內(nèi)部好多都是基于接口的,所以需要找對(duì)應(yīng)的實(shí)現(xiàn)的話可以看它的服務(wù)注冊(cè)是注冊(cè)的哪一個(gè)服務(wù)即可。

簡(jiǎn)單分析一下,Ocelot 的路由匹配過(guò)程一定在尋找下游地址的時(shí)候,根據(jù)上游的請(qǐng)求信息(直接請(qǐng)求網(wǎng)關(guān)的請(qǐng)求)匹配,所以我們首先找到 DownstreamRouteFinderMiddleware https://github.com/ThreeMammals/Ocelot/blob/13.5.2/src/Ocelot/DownstreamRouteFinder/Middleware/DownstreamRouteFinderMiddleware.cs

由上面的代碼,我們可以看到,下游路由地址是通過(guò) IDownstreamRouteFinder 來(lái)找下游路由的,轉(zhuǎn)到對(duì)應(yīng)的實(shí)現(xiàn)代碼:https://github.com/ThreeMammals/Ocelot/blob/13.5.2/src/Ocelot/DownstreamRouteFinder/Finder/DownstreamRouteFinder.cs

這里我們可以看到是通過(guò) IUrlPathToUrlTemplateMatcher 來(lái)進(jìn)行路由匹配的,所以我們需要用到這個(gè)服務(wù),然后看這個(gè) Match 方法的參數(shù),前兩個(gè)參數(shù)比較明確,第一個(gè)參數(shù)是上游請(qǐng)求的地址,第二個(gè)參數(shù)是請(qǐng)求的 queryString,第三個(gè)參數(shù)則是 Ocelot 內(nèi)部構(gòu)建出來(lái)的路由模板信息 UpstreamPathTemplate,然后我們就需要知道怎么構(gòu)建一個(gè) UpstreamPathTemplate 對(duì)象,繼續(xù)探索

直接看 UpstreamPathTemplate,表示一臉懵逼,不知道怎么構(gòu)建, 全局搜素了一下,發(fā)現(xiàn)有一個(gè) IUpstreamTemplatePatternCreator 里面定義了一個(gè) Create 的方法

這個(gè)方法看上去簡(jiǎn)單了好多,查看 IReRoute 的定義 https://github.com/ThreeMammals/Ocelot/blob/13.5.2/src/Ocelot/Configuration/File/IReRoute.cs

我們只需要根據(jù)路徑模板構(gòu)建一個(gè) IReRoute 對(duì)象即可,Ocelot 中有一個(gè)實(shí)現(xiàn)了 IReRoute 的類 FileReRoute,但是感覺(jué)有些復(fù)雜,就沒(méi)有用,自定義了一個(gè)類型實(shí)現(xiàn)了 IReRoute

自此,我們就已經(jīng)找到了要使用 Ocelot 路由匹配所需要的服務(wù)了:

  • IUrlPathToUrlTemplateMatcher

  • IUpstreamTemplatePatternCreator

使用 Ocelot 路由匹配

上面提到了我們沒(méi)有使用 FileReRoute 對(duì)象,所以我們就需要自定義一個(gè) IReRoute 對(duì)象:

private class FakeReRoute : IReRoute {public string UpstreamPathTemplate { get; set; }public bool ReRouteIsCaseSensitive { get; set; }public int Priority { get; set; } }

使用 Ocelot 路由匹配示例:

public class UrlBasedAuthenticationMiddleware : Ocelot.Middleware.OcelotMiddleware {private readonly GatewayOptions _gatewayOptions;private readonly IMemoryCache _memoryCache;private readonly OcelotRequestDelegate _next;private readonly IUrlPathToUrlTemplateMatcher _urlTemplateMatcher;private readonly IUpstreamTemplatePatternCreator _templatePatternCreator;public UrlBasedAuthenticationMiddleware(OcelotRequestDelegate next, IOptions<GatewayOptions> options, IMemoryCache memoryCache, IOcelotLoggerFactory loggerFactory,IUrlPathToUrlTemplateMatcher urlTemplateMatcher,IUpstreamTemplatePatternCreator templatePatternCreator): base(loggerFactory.CreateLogger<UrlBasedAuthenticationMiddleware>()){_next = next;_gatewayOptions = options.Value;_memoryCache = memoryCache;_urlTemplateMatcher = urlTemplateMatcher;_templatePatternCreator = templatePatternCreator;}public async Task Invoke(DownstreamContext context){var permissions = await _memoryCache.GetOrCreateAsync(_gatewayOptions.ApiPermissionsCacheKey, async entry =>{using (var conn = new SqlConnection(_gatewayOptions.PermissionsConnectionString)){entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);return (await conn.QueryAsync<ApiPermission>(@"")).Select(_ => _.GetViewModel()).ToArray();}});var request = context.HttpContext.Request;var permission = permissions.FirstOrDefault(p =>request.Path.Value.Equals(p.PathPattern, StringComparison.OrdinalIgnoreCase) &&p.Method == request.Method.ToUpper());if (null == permission){permission = permissions.FirstOrDefault(p =>p.Method == request.Method.ToUpper() &&_urlTemplateMatcher.Match(request.Path.Value, request.QueryString.Value,_templatePatternCreator.Create(new FakeReRoute(){UpstreamPathTemplate = p.PathPattern})).Data.Match);}// ...await _next.Invoke(context);}private class FakeReRoute : IReRoute{public string UpstreamPathTemplate { get; set; }public bool ReRouteIsCaseSensitive { get; set; }public int Priority { get; set; }} }

More

這樣,apiPermission 的 Path 配置基本可以使用和 Ocelot 配置一樣的路由,可以更方便的配置,避免 996 咯

Reference

  • https://github.com/ThreeMammals/Ocelot

  • https://github.com/ThreeMammals/Ocelot/blob/13.5.2/src/Ocelot/DependencyInjection/OcelotBuilder.cs#L95

  • https://github.com/ThreeMammals/Ocelot/blob/13.5.2/src/Ocelot/DownstreamRouteFinder/UrlMatcher/IUrlPathToUrlTemplateMatcher.cs

總結(jié)

以上是生活随笔為你收集整理的使用 Ocelot 匹配路由的方法匹配路由的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。