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

如何配置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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 19:47:06