.NET Core 微服务的 JWT 认证应放在 Kong 还是 YARP?
结论:可以先在 YARP 校验 JWT,微服务保留自己的授权边界
对于这套包含 5 至 6 个服务的架构,可以由 Kong 处理计划中的入口流量策略,YARP 使用 ASP.NET Core 校验 JWT 并执行接口级授权,各微服务再校验访问本服务的令牌并执行业务授权。这个方案不需要 Service Mesh。
如果 Kong 所用的认证插件能满足身份提供方接入、令牌校验和密钥轮换要求,也可以让 Kong 提前拒绝无效令牌。是否这样做取决于入口治理需求,没有必须把所有认证逻辑集中在某一层的通用规定。
登录和令牌签发由身份提供方负责,JWT 校验用于确认请求身份,授权则用于判断该身份能否执行当前操作。即使 Kong 或 YARP 已校验令牌,用户也不会因此自动获得所有下游资源的访问权限。ASP.NET Core JWT Bearer 认证文档
各层应负责什么
| 位置 | 建议职责 |
|---|---|
| 身份提供方 | 用户登录、签发令牌、刷新令牌和管理签名密钥 |
| Kong | 入口流量策略;具备合适配置时,提前校验令牌并拒绝无效请求 |
| YARP / BFF | 校验访问自身受保护入口的凭据,执行路由级授权,组织下游调用 |
| 微服务 | 校验访问本服务的凭据,执行 scope、角色、租户和资源归属等授权检查 |
例如,网关可以检查调用者是否具备读取订单的权限,但订单是否属于当前用户,通常需要由订单服务判断。订单服务掌握业务数据,也应负责这项授权规则。
不要仅凭客户端传来的 X-User-Id、X-Roles 等请求头确认身份。如果采用网关注入身份头的方式,还需要建立可信代理链、清除外部同名头,并阻止绕过网关的访问。对当前规模的系统,直接在服务中校验 JWT 通常更容易明确边界。
在 YARP 中如何实现
YARP 可以使用 ASP.NET Core 的认证和授权组件保护代理路由。它默认不会自动保护所有请求,需要显式配置授权策略或为代理端点要求授权。YARP 认证与授权文档
下面的示例适用于使用现代 Program.cs 托管方式的项目。项目需要引用与目标框架兼容的 Microsoft.AspNetCore.Authentication.JwtBearer 和 Yarp.ReverseProxy 包。
using Microsoft.AspNetCore.Authentication.JwtBearer;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority =
builder.Configuration["Authentication:Authority"];
options.Audience =
builder.Configuration["Authentication:Audience"];
options.RequireHttpsMetadata = true;
});
builder.Services.AddAuthorization();
builder.Services
.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapReverseProxy().RequireAuthorization();
app.Run();
在已有配置中补充身份提供方和 API audience。以下地址与名称仅为占位示例:
{
"Authentication": {
"Authority": "https://identity.example.com",
"Audience": "microservices-api"
}
}
这里假设身份提供方提供兼容的发现文档及签名公钥,且令牌的 iss、aud 与配置匹配。不要为了让请求通过而关闭签名、签发方、受众或有效期校验。
示例通过 RequireAuthorization() 保护所有代理端点。如果有匿名接口,应根据实际路由设计配置例外;如果不同路由需要不同权限,可以使用 YARP 的 AuthorizationPolicy。接口聚合代码通过 HttpClient 主动调用下游时,也需要自行处理下游访问凭据。
Kong 校验与下游校验如何配合
Kong 可以承担第一道令牌检查,但应先核实所选插件的能力。Kong 的 JWT 插件使用 Consumer 关联 JWT credentials,并提供签名及部分声明检查;不能仅凭插件名称,就假定它已完成外部身份提供方的全部校验和密钥轮换配置。Kong JWT 插件文档
如果 Kong 已校验 JWT,而 YARP 还需要根据用户身份执行策略,YARP 仍需要通过可信方式建立用户身份。让 YARP 再校验一次令牌是一种直接的做法。JWT 签名通常可以使用缓存的公钥在本地校验,无须每次请求都向登录服务发起查询。
下游服务能否继续使用原令牌,取决于令牌的受众设计:
- 如果多个服务共同组成一个逻辑 API,并约定接受同一个 audience,可以在该信任范围内转发原访问令牌。
- 如果各服务要求不同 audience,就需要为目标服务取得适用的访问令牌,不能直接关闭 audience 校验来复用令牌。
YARP 在正常代理请求时可以传递 Authorization 请求头,但下游仍需要校验并解释收到的凭据。YARP 凭据传递说明
部署前确认两个前提
第一,明确 BFF 是否管理浏览器登录会话。如果浏览器发送的是会话 Cookie,JWT 保存在 BFF 服务端,那么 Kong 看到的请求可能没有 Bearer JWT。此时应由 BFF 校验会话,再携带适用的访问令牌调用微服务,同时处理 Cookie 会话对应的 CSRF 防护。这与浏览器直接发送 JWT 的流程不同。
第二,在 ECS 中限制服务的入口范围,让 YARP 和微服务只接受预期来源的连接,并使用合适的传输加密。网络访问限制与应用层认证需要配合使用,不引入 Service Mesh 也能完成这些职责。
上线前至少验证:缺少或失效令牌时返回 401;身份有效但权限不足时返回 403;错误 audience 的令牌无法访问目标服务;用户不能读取其他用户或租户的数据。
备注:内容仅供参考。
