在 Ocelot API Gateway 中的特定路由中添加 Authorization Header(Authorization: Bearer access_token)

Posted

技术标签:

【中文标题】在 Ocelot API Gateway 中的特定路由中添加 Authorization Header(Authorization: Bearer access_token)【英文标题】:Adding Authorization Header (Authorization: Bearer access_token) to specific route in Ocelot API Gateway在 Ocelot API Gateway 中的特定路由中添加 Authorization Header(Authorization: Bearer access_token) 【发布时间】:2021-05-03 20:58:09 【问题描述】:

我有一个 Web 应用程序通过 Ocelot API 网关向不同的 API 发出请求。其中一个端点需要通过 JWT 以“授权:承载 access_token”(将其标识为承载/令牌认证方案的“承载”关​​键字)格式作为授权标头发送的身份验证。此令牌特定于应用程序,不用于向网关进行身份验证(网关使用不同的身份验证方案),而是将其作为声明存储在应用程序的安全 HttpOnly cookie 中。

虽然 Ocelot 确实支持将声明转换为标头 (https://ocelot.readthedocs.io/en/latest/features/claimstransformation.html),但

"AddHeadersToRequest": 
    "HeaderName": "Claims[ClaimName] > value[0] > |"
,

它只支持一个值,不支持动态标题/字符串连接。换句话说

"AddHeadersToRequest": 
    "Authorization": "Bearer Claims[ClaimName] > value[0] > |"
,

不起作用(这样的请求显然会导致错误 401)。所以我的问题是,如何将适当的授权标头/承载令牌添加到特定的 Ocelot 路由?

【问题讨论】:

【参考方案1】:

委派处理程序 (https://docs.microsoft.com/en-us/dotnet/api/system.net.http.delegatinghandler?view=net-5.0, https://ocelot.readthedocs.io/en/latest/features/delegatinghandlers.html ),在请求发送之前添加“东西”,结果证明非常适合这项任务。由于 Ocelot 声明转换发生在调用之前,因此只需将声明转换为标头,然后连接它们的值并将它们添加为新的标头。

首先编辑ocelot.json:

"AddHeadersToRequest": 
    "AccessToken": "Claims[AccessToken] > value[0] > |"
,
"DelegatingHandlers": [
    "HeaderDelegatingHandler"
]

然后创建一个继承自 DelegatingHandler 的 HeaderDelegatingHandler 类:

public class HeaderDelegatingHandler : DelegatingHandler

    private readonly IHttpContextAccessor _httpContextAccessor;

    public HeaderDelegatingHandler (IHttpContextAccessor httpContextAccessor)
    
        _httpContextAccessor = httpContextAccessor;
    

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    
        IEnumerable<string> headerValues;
        if (request.Headers.TryGetValues("AccessToken", out headerValues))
        
            string accessToken = headerValues.First();

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            request.Headers.Remove("AccessToken");
        

        return await base.SendAsync(request, cancellationToken);
    

记得将 Delegating Handler 添加到 ConfigureServices(可以设置为全局或不设置):

services.AddOcelot()
        .AddDelegatingHandler<HeaderDelegatingHandler>();

Tom Pallister (https://github.com/ThreeMammals/Ocelot/issues/468)、rh101 (https://github.com/ThreeMammals/Ocelot/issues/1267#issuecomment-649299048) 和 PaulD (https://***.com/a/60609784/2768479) 的帖子阐明了这个问题。

【讨论】:

以上是关于在 Ocelot API Gateway 中的特定路由中添加 Authorization Header(Authorization: Bearer access_token)的主要内容,如果未能解决你的问题,请参考以下文章

Ocelot API Gateway 错误:无法建立连接,因为目标机器主动拒绝它

Ocelot api gateway - kubernetes - error: "namespace:serviceservice:managementservice Unable to

Ocelot实现API网关服务

微服务-网关GateWay

将特定 AWS API Gateway 阶段连接到 CloudFormation 模板中的特定 Lambda 别名

微服务之:从零搭建ocelot网关和consul集群