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

.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:27:03