如何配置.NET Core以兼容Node.js生成的JWT令牌?
问题:.NET Core无法验证Node.js生成的JWT令牌
我们拥有旧Node.js后端,用户登录时生成JWT令牌;同时开发新C# .NET Core后端,计划逐步替换旧接口实现无缝过渡。存在场景:用户通过旧后端登录获取JWT后调用新接口,新后端需接受该令牌。已将两端密钥设为相同,但Node.js生成的令牌仍无法被.NET Core接受。
Node.js生成JWT的代码
import * as jwt from 'jsonwebtoken'; function signToken(id, role) { return jwt.sign( { _id: id, role: role }, config.secrets.session, { expiresIn: 60 * 60 * 24 * 7 } ); }
.NET Core端验证令牌的代码(Program.cs)
public static IApplicationBuilder UseAuthentication(this IApplicationBuilder app) { app.Properties[AuthenticationMiddlewareSetKey] = true; return app.UseMiddleware<AuthenticationMiddleware>(); } public static IApplicationBuilder UseAuthorization(this IApplicationBuilder app) { VerifyServicesRegistered(app); app.Properties[AuthorizationMiddlewareSetKey] = true; return app.UseMiddleware<AuthorizationMiddlewareInternal>(); } public static void ConfigureJwtHandler(this WebApplicationBuilder builder) { var jwtIssuer = builder.Configuration.GetSection("Jwt:Issuer").Get<string>(); var jwtKey = builder.Configuration.GetSection("Jwt:Key").Get<string>(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = false, ValidateIssuerSigningKey = false, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey)), }; options.Authority = "http://localhost:5250"; options.RequireHttpsMetadata = false; }); builder.Services.AddAuthorization(options => { options.AddPolicy("myUser", policy => policy.RequireClaim("role")); }); } ... var builder = WebApplication.CreateBuilder(args); builder.ConfigureJwtHandler(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.Run();
报错信息
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature key was not found"
解决方案
问题核心在于.NET Core的JWT配置中options.Authority的设置,该属性会让中间件尝试从指定的权威服务器获取签名密钥,直接忽略了你手动配置的IssuerSigningKey,导致密钥匹配失败。修改步骤如下:
- 移除
options.Authority配置:删除options.Authority = "http://localhost:5250";这一行,让中间件使用你手动指定的密钥验证签名。 - 启用
ValidateIssuerSigningKey:将ValidateIssuerSigningKey = false改为true,确保中间件验证签名密钥的有效性。 - 恢复
ValidateLifetime为true(可选但推荐):令牌有效期验证是安全必要环节,测试完成后建议开启。
修改后的ConfigureJwtHandler方法代码:
public static void ConfigureJwtHandler(this WebApplicationBuilder builder) { var jwtKey = builder.Configuration.GetSection("Jwt:Key").Get<string>(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, // 恢复有效期验证 ValidateIssuerSigningKey = true, // 启用密钥验证 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey)), }; options.RequireHttpsMetadata = false; }); builder.Services.AddAuthorization(options => { options.AddPolicy("myUser", policy => policy.RequireClaim("role")); }); }
可行性说明
完全可行。JWT是跨平台的标准令牌格式,只要两端使用相同的签名算法(Node.js的jsonwebtoken默认使用HS256,.NET Core的SymmetricSecurityKey默认也匹配HS256)、密钥,并且验证参数(如issuer、audience)保持一致或关闭对应验证,就能实现跨系统的JWT验证。
内容的提问来源于stack exchange,提问作者Zoltan Hernyak
相关产品推荐
相关产品推荐

