如何配置Identity Server在微服务中签发JWT替代Cookie实现认证?
问题描述
我为微服务应用搭建了认证服务,现有代码如下:
Program.cs
using System.Security.Claims; using AuthMicroservice; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; WebApplicationBuilder builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddCors(options => { options.AddPolicy("AllowLocalhost", builder => { builder.WithOrigins("http://localhost:3000") .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials(); }); }); builder.Services.AddAuthorization(); builder.Services.AddAuthentication(IdentityConstants.ApplicationScheme) .AddCookie(IdentityConstants.ApplicationScheme) .AddBearerToken(IdentityConstants.BearerScheme); builder.Services.AddIdentityCore<User>() .AddEntityFrameworkStores<AppDbContext>() .AddApiEndpoints(); builder.Services.AddDbContext<AppDbContext>(options => options.UseNpgsql(builder.Configuration.GetConnectionString("UsersDb"))); WebApplication app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); app.ApplyMigrations(); } app.UseHttpsRedirection(); app.UseCors("AllowLocalhost"); app.MapGet("users/me", async (ClaimsPrincipal claims, AppDbContext context) => { string userId = claims.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value; return await context.Users.FindAsync(userId); }) .RequireAuthorization(); app.MapIdentityApi<User>(); app.Run();
DbContext代码
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace AuthMicroservice; public class AppDbContext : IdentityDbContext<User> { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } }
当前已通过自动端点实现了基于Cookie的完整认证,但在微服务场景下,我希望使用JWT令牌。请问如何让认证服务的自动端点生成JWT令牌而非Cookie?以及如何在其他微服务中验证这些令牌?
解决方案
一、修改认证服务,生成JWT令牌替代Cookie
你的代码已经引入了AddBearerToken,但默认认证方案是Cookie,需调整配置让自动端点返回JWT令牌:
1. 调整认证核心配置
将默认认证方案改为Bearer令牌方案,移除冗余的Cookie认证(若无需Cookie登录场景),同时配置令牌的签名密钥与有效期:
修改后的Program.cs关键代码:
using System.Text; using Microsoft.IdentityModel.Tokens; builder.Services.AddAuthorization(); // 设置默认认证方案为Bearer令牌 builder.Services.AddAuthentication(IdentityConstants.BearerScheme) .AddBearerToken(IdentityConstants.BearerScheme, options => { // 配置令牌验证参数 options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SigningKey"])), ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true }; // 配置令牌有效期(默认1小时,可按需调整) options.TokenExpiration = TimeSpan.FromHours(1); }); // 其余代码保持不变...
2. 添加JWT配置项
在appsettings.json中添加令牌相关配置(生产环境需使用强签名密钥,建议长度≥32位):
{ "Jwt": { "Issuer": "http://localhost:5000", // 你的认证服务地址 "Audience": "microservices-audience", // 统一受众标识 "SigningKey": "your-strong-production-signing-key-here" } }
3. 验证端点行为
启动认证服务后,调用自动生成的/login端点,响应体将返回JWT令牌而非设置Cookie,示例响应:
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "CfDJ8..." }
二、在其他微服务中验证JWT令牌
其他微服务需配置JWT验证中间件,确保仅携带有效令牌的请求可访问受保护资源:
1. 配置认证与授权服务
在目标微服务的Program.cs中添加以下代码:
using System.Text; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; var builder = WebApplication.CreateBuilder(args); // 添加JWT Bearer认证 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SigningKey"])), ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true }; }); builder.Services.AddAuthorization(); // 其余服务配置... var app = builder.Build(); // 启用认证与授权中间件(顺序不能错) app.UseAuthentication(); app.UseAuthorization(); // 受保护端点示例 app.MapGet("/api/protected", () => "仅授权用户可访问此内容") .RequireAuthorization(); app.Run();
2. 同步配置文件
目标微服务的appsettings.json需添加与认证服务完全一致的JWT配置:
{ "Jwt": { "Issuer": "http://localhost:5000", "Audience": "microservices-audience", "SigningKey": "your-strong-production-signing-key-here" } }
3. 发起验证请求
客户端请求时,需在Authorization请求头中携带令牌:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
内容的提问来源于stack exchange,提问作者user29547398
相关产品推荐
相关产品推荐

