在 Ocelot API 网关中间件中返回未授权

Posted

技术标签:

【中文标题】在 Ocelot API 网关中间件中返回未授权【英文标题】:Return unauthorized in Ocelot API Gateway Middleware 【发布时间】:2021-10-29 13:20:53 【问题描述】:

此时,我的微服务中有一个 Ocelot API 网关,但我最近正在研究如何使 JWT 无效,而在我的项目中做到这一点的最佳方法是使用黑名单,所以我决定使用用于检查我的 Redis 缓存无效 JWT 列表的中间件预授权。如果令牌在缓存中,我已经寻找强制返回带有自定义消息的 401 的解决方案,但我找不到功能性解决方案。以下是我的尝试:

public async void Configure(IApplicationBuilder app, IWebHostEnvironment env, IDistributedCache cache) 
    if (env.IsDevelopment()) 
        app.UseDeveloperExceptionPage();
    

    app.UseRouting();

    app.UseCors();

    app.UseAuthentication();

    app.UseAuthorization();

    app.UseEndpoints(endpoints => 
        endpoints.MapGet("/", async context => 
            await context.Response.WriteAsync("Hello World!");
        );
    );

    var configuration = new OcelotPipelineConfiguration 
        PreAuthorizationMiddleware = async (ctx, next) => 
            string token = ctx.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");

            if (!string.IsNullOrEmpty(token)) 
                string blacklist = await cache.GetStringAsync(token);

                if (!string.IsNullOrEmpty(blacklist)) 
                    ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    await ctx.Response.WriteAsync("Custom Message");

                    return;
                
            

            await next.Invoke();
        
    ;

    await app.UseOcelot(configuration);

有人可以帮助我吗?我尝试过的解决方案仅返回 HTTP 状态代码 500 或始终返回 401。

【问题讨论】:

【参考方案1】:

一旦您进入 Ocelot 的流程,您就必须玩 Ocelot 的游戏。它使用HttpContext.Items 字典上的特殊对象和扩展方法在中间件之间传递数据。特别是对于错误,它有 2 个扩展方法 SetErrorUpsertErrors。所以你需要在检查黑名单后添加这个:

if (!string.IsNullOrEmpty(blacklist))

    ctx.Items.SetError(new UnauthorizedError("your custom message"));
    return;

【讨论】:

您的解决方案有效,但没有收到未经授权的 401,而是响应 403 被禁止,在我的调试控制台中,消息是 Ocelot.Responder.Middleware.ResponderMiddleware: Warning: requestId: 40000002-0008-f900-b63f-84710c7967bb, previousRequestId: no previous request id, message: Error Code: UnauthorizedError Message: Custom errors found in ResponderMiddleware. Setting error response for request path: /my/path/here, request method: GET 您要求未经授权的主题,所以我为您提供了 403 的解决方案。如果您想要 401 - 未经身份验证,请改用 new UnauthenticatedError 如果您需要 401,可能会有更好的方法来处理已撤销的令牌。例如,如果您将 Okta 用于 OIDC,则最好使用自省而不是本地令牌验证。对于 IdentityServer,请使用参考令牌。否则实现自定义 AuthenticationHandler 并在那里执行黑名单查找

以上是关于在 Ocelot API 网关中间件中返回未授权的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Azure Active Directory 设置 Ocelot Api 网关

Ocelot和IdentityServer4初体验

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

ocelot 自定义认证和授权

asp.net core网关Ocelot的简单介绍& Ocelot集成Identity认证

API网关Ocelot 使用Polly 处理部分失败问题