You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Ocelot的.NET微服务网关如何实现JWT授权与API Key转发

Ocelot网关统一JWT校验+自动API Key注入实现方案

你考虑的DelegatingHandler确实能实现需求,但不是最优选择——它作用于Ocelot内部转发的HTTP客户端实例,执行时机偏后,无法直接复用Ocelot内置的路由匹配、认证能力,后续维护授权规则的成本比较高。
更推荐用Ocelot原生管道扩展+路由元数据配置的方案,全程不需要编写任何网关侧的业务控制器,所有逻辑和路由配置绑定,对原有服务无侵入。

具体实现步骤

1. 网关注入JWT认证能力

直接复用.NET和Ocelot原生的JWT认证组件,不需要自己写令牌校验逻辑,校验参数和现有Authentication Provider服务保持一致即可:

// Program.cs 服务注册部分
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication("GatewayJwt")
    .AddJwtBearer("GatewayJwt", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = "你的认证服务标识",
            ValidateAudience = true,
            ValidAudience = "微服务集群标识",
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("JWT签名密钥"))
        };
    });
builder.Services.AddAuthorization();
builder.Services.AddOcelot();

2. 给目标路由配置认证规则和元数据

不需要写额外控制器,直接在ocelot.json中给需要API Key转发的路由绑定认证方案、要求的Claims规则、对应下游服务的API Key即可,其他原有路由保持原有配置不受影响:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/新微服务接口路径/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [{"Host": "新微服务地址", "Port": 服务端口}],
      "UpstreamPathTemplate": "/api/new-service/{everything}",
      "UpstreamHttpMethod": ["Get", "Post", "Put", "Delete"],
      // 绑定该路由需要走的JWT认证方案
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "GatewayJwt",
        "AllowedScopes": []
      },
      // 自定义元数据:配置授权规则和下游API Key
      "Metadata": {
        "RequiredClaim": "permission:access_new_service",
        "TargetApiKey": "该微服务分配的有效API Key"
      }
    }
    // 其他原有路由不需要网关认证的话,不用加上述配置,保持原有逻辑即可
  ]
}

3. 编写轻量管道中间件完成校验和请求头注入

中间件嵌入Ocelot原生请求管道,在路由匹配、JWT校验完成后执行:判断当前路由是否配置了API Key转发规则,校验JWT中的Claims是否满足要求,校验通过就给请求头注入API Key,不通过直接返回403:

public class ApiKeyInjectMiddleware
{
    private readonly RequestDelegate _next;
    public ApiKeyInjectMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext context)
    {
        var currentRoute = context.Items.DownstreamRoute();
        // 没有配置API Key元数据的路由直接跳过,走原有逻辑
        if (currentRoute?.Metadata == null 
            || !currentRoute.Metadata.ContainsKey("TargetApiKey")
            || !currentRoute.Metadata.ContainsKey("RequiredClaim"))
        {
            await _next(context);
            return;
        }
        // 校验Claims
        var requiredClaim = currentRoute.Metadata["RequiredClaim"].Split(':');
        var claimType = requiredClaim[0];
        var claimValue = requiredClaim.Length > 1 ? requiredClaim[1] : null;
        var claimValid = context.User.Claims.Any(c => 
            c.Type == claimType && (claimValue == null || c.Value == claimValue)
        );
        if (!claimValid)
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            return;
        }
        // 注入API Key请求头,Ocelot转发时会自动携带
        context.Request.Headers.TryAdd("X-Api-Key", currentRoute.Metadata["TargetApiKey"]);
        await _next(context);
    }
}

public static class ApiKeyInjectMiddlewareExtensions
{
    public static IApplicationBuilder UseApiKeyInject(this IApplicationBuilder app)
        => app.UseMiddleware<ApiKeyInjectMiddleware>();
}

4. 按正确顺序注册中间件

注意中间件顺序,必须放在认证授权之后、Ocelot核心转发逻辑之前,才能拿到已经校验完成的用户身份信息:

// Program.cs 中间件管道配置
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
// 注册自定义API Key注入中间件
app.UseApiKeyInject();
// 接入Ocelot核心逻辑
await app.UseOcelot();
app.Run();

方案优势

  • 零额外控制器代码:新增需要网关认证+API Key转发的微服务时,只需要在ocelot.json中添加对应路由配置即可,不需要修改网关业务代码。
  • 兼容现有逻辑:未配置元数据的原有路由完全走之前的下游独立认证流程,支持灰度收敛认证逻辑,不需要一次性全量改造。
  • 灵活可扩展:如果后续需要支持复杂授权规则(多Claims校验、角色校验、动态拉取API Key),只需要修改中间件逻辑即可,所有路由统一生效。如果对安全性要求高,还可以去掉配置文件中的明文API Key,在中间件中根据路由信息从密钥管理服务动态拉取对应密钥。

内容的提问来源于stack exchange,提问作者Vlad Radu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 23:48:26