下游主机的 Ocelot 占位符

问题描述 投票:0回答:1

我有一个 API Gateway 使用

.NET Core 3.1
Ocelot
中运行。一切都按预期正常工作。

现在我正在尝试在中间件过程中替换下游主机。

这是我的configuration.json

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/product/getProduct",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": "44300"
        }
      ],
      "UpstreamPathTemplate": "/getProduct"
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://localhost:62012/"
  }
}

我想在运行时更改

Host
中的
DownstreamHostAndPorts
,因为此时从
jwt
中获取声明,我将知道用户所属的租户,因此知道将请求路由到哪里。

更清楚地说,对网关的请求来自 http://localhost:62012/api/getProduct,

然后我从发出此调用的请求中的

jwt
获取租户,然后将请求重定向到相关的
api
,如下所示

http://tenant1.com/api/product/getProduct 或者 http://tenant2.com/api/product/getProduct

c# api gateway ocelot
1个回答
3
投票

您需要创建自定义中间件并将其注入到

Authentication
中间件之后。最好的扩展点是
PreAuthorisationMiddleware
。假设您有一项服务可以通过用户声明解析租户 uri,如下所示:

public interface ITenantHostResolver
{
    Task<Uri> Resolve(ClaimsPrincipal claimsPrincipal);
}

在您的

Startup
类中注入将覆盖下游设置的中间件:

public void Configure(IApplicationBuilder app)
{

    var conf = new OcelotPipelineConfiguration
    {
        PreAuthorizationMiddleware = async (httpContext, next) =>
        {
            if(!httpContext.Request.Path.Equals("/api/product/getProduct"))
            {
                await next.Invoke();

                return;
            }

            var claimsPrincipal = httpContext.User;

            var tenantHostResolver = httpContext.RequestServices.GetRequiredService<ITenantHostResolver>();

            var tenantHostAndPort = await tenantHostResolver.Resolve(claimsPrincipal);

            var downstreamRequest = httpContext.Items.DownstreamRequest();

            downstreamRequest.Host = tenantHostAndPort.Host;

            downstreamRequest.Port = tenantHostAndPort.Port;

            downstreamRequest.Scheme = tenantHostAndPort.Scheme;

            await next.Invoke();
        }
    };

    app.UseCustomOcelot(conf).Wait();
}
© www.soinside.com 2019 - 2024. All rights reserved.