.Net 5微服务集成测试如何模拟Jwt Bearer令牌通过授权校验
集成测试模拟JWT认证的实现方案
方案1:自签名JWT+重写认证配置(最常用,无需依赖外部服务)
该方案不需要修改业务代码,仅在测试环境替换认证逻辑,用自定义密钥生成和验证JWT令牌,无需请求真实授权服务器。
步骤1:自定义测试用WebApplicationFactory
在集成测试项目中创建继承自WebApplicationFactory<Startup>的工厂类,重写配置逻辑替换原有JWT认证规则:
public class TestWebApplicationFactory : WebApplicationFactory<Startup> { // 测试用对称签名密钥,长度至少16位即可自定义 public static readonly SymmetricSecurityKey TestSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("自定义测试用足够长度的签名密钥12345678")); protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.ConfigureServices(services => { // 移除原有JWT认证相关配置 var jwtOptionsDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IConfigureOptions<JwtBearerOptions>)); if (jwtOptionsDescriptor != null) { services.Remove(jwtOptionsDescriptor); } var authSchemeDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IAuthenticationSchemeProvider)); if (authSchemeDescriptor != null) { services.Remove(authSchemeDescriptor); } // 添加测试用JWT认证配置 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, // 和生产配置保持一致 ValidateLifetime = true, IssuerSigningKey = TestSigningKey, ClockSkew = TimeSpan.Zero }; }); }); } }
步骤2:编写测试用JWT生成工具
public static class TestJwtGenerator { public static string GenerateToken(Claim[] customClaims = null) { customClaims ??= Array.Empty<Claim>(); var signingCredentials = new SigningCredentials( TestWebApplicationFactory.TestSigningKey, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( expires: DateTime.Now.AddHours(2), claims: customClaims, signingCredentials: signingCredentials); return new JwtSecurityTokenHandler().WriteToken(token); } }
步骤3:改造集成测试用例
请求时携带生成的测试令牌即可正常访问受保护端点:
[Fact] public async Task ProtectedEndpoint_ShouldReturnSuccess_WithValidToken() { // 初始化测试服务和客户端 await using var factory = new TestWebApplicationFactory(); var client = factory.CreateClient(); // 生成携带自定义声明的测试令牌(满足角色、策略等授权校验需求) var token = TestJwtGenerator.GenerateToken(new[] { new Claim(ClaimTypes.Name, "TestUser"), new Claim(ClaimTypes.Role, "Admin") }); // 挂载认证头 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); // 发起请求验证结果 var response = await client.GetAsync("/api/your-protected-endpoint"); response.EnsureSuccessStatusCode(); }
方案2:模拟真实授权服务器响应(完全对齐生产配置)
如果需要完全复用生产环境的认证配置不做修改,可以使用WireMock.NET模拟授权服务器的OIDC元数据和公钥接口:
- 测试启动时启动WireMock本地服务
- 将应用配置中的
Authorization:Authority替换为WireMock的监听地址 - 配置WireMock返回符合预期的OIDC发现文档、JWKS公钥响应,公钥与生成测试JWT的密钥匹配
- 后续请求流程和方案1一致,携带自定义生成的JWT即可
内容的提问来源于stack exchange,提问作者Bunnynut
相关产品推荐
相关产品推荐

