下游主机的 Ocelot 占位符
Ocelot placeholder for downstream host
我在 .NET Core 3.1
使用 Ocelot
有一个 API 网关 运行。一切正常,如预期。
现在我正在尝试在中间件过程中替换下游主机。
这是我的 configuration.json:
{
"Routes": [
{
"DownstreamPathTemplate": "/api/product/getProduct",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": "44300"
}
],
"UpstreamPathTemplate": "/getProduct"
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:62012/"
}
}
我想在运行时更改 DownstreamHostAndPorts
中的 Host
,因为此时从 jwt
中获取声明 我将知道用户所属的租户知道在哪里发送请求。
说得更清楚一点,网关的请求来自 http://localhost:62012/api/getProduct,
然后我从进行此调用的请求中的 jwt
中获取租户,然后将请求重定向到相关的 api
,就像这样
http://tenant1.com/api/product/getProduct
要么
http://tenant2.com/api/product/getProduct
您需要创建自定义中间件并将其注入到 Authentication
中间件之后。最好的扩展点是 PreAuthorisationMiddleware
。假设您有一项服务可以通过用户声明解析租户 uri,如下所示:
public interface ITenantHostResolver
{
Task<Uri> Resolve(ClaimsPrincipal claimsPrincipal);
}
在您的 Startup
class 中注入将覆盖下游设置的中间件:
public void Configure(IApplicationBuilder app)
{
var conf = new OcelotPipelineConfiguration
{
PreAuthorisationMiddleware = async (httpContext, next) =>
{
if(!httpContext.Request.Path.Equals("/api/product/getProduct"))
{
await _next.Invoke(httpContext);
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();
}
我在 .NET Core 3.1
使用 Ocelot
有一个 API 网关 运行。一切正常,如预期。
现在我正在尝试在中间件过程中替换下游主机。
这是我的 configuration.json:
{
"Routes": [
{
"DownstreamPathTemplate": "/api/product/getProduct",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": "44300"
}
],
"UpstreamPathTemplate": "/getProduct"
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:62012/"
}
}
我想在运行时更改 DownstreamHostAndPorts
中的 Host
,因为此时从 jwt
中获取声明 我将知道用户所属的租户知道在哪里发送请求。
说得更清楚一点,网关的请求来自 http://localhost:62012/api/getProduct,
然后我从进行此调用的请求中的 jwt
中获取租户,然后将请求重定向到相关的 api
,就像这样
http://tenant1.com/api/product/getProduct 要么 http://tenant2.com/api/product/getProduct
您需要创建自定义中间件并将其注入到 Authentication
中间件之后。最好的扩展点是 PreAuthorisationMiddleware
。假设您有一项服务可以通过用户声明解析租户 uri,如下所示:
public interface ITenantHostResolver
{
Task<Uri> Resolve(ClaimsPrincipal claimsPrincipal);
}
在您的 Startup
class 中注入将覆盖下游设置的中间件:
public void Configure(IApplicationBuilder app)
{
var conf = new OcelotPipelineConfiguration
{
PreAuthorisationMiddleware = async (httpContext, next) =>
{
if(!httpContext.Request.Path.Equals("/api/product/getProduct"))
{
await _next.Invoke(httpContext);
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();
}