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

.NET Core 6 Web服务JWT认证Token模拟实现教程求助

.NET 6 无 Startup.cs 架构下单元测试模拟JWT Token实现示例

1. 自定义测试用WebApplicationFactory

创建继承自WebApplicationFactory<TProgram>的工厂类,在ConfigureWebHost中对齐测试环境与生产环境的JWT认证核心配置,同时内置Token生成方法:

public class TestWebAppFactory : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            // 配置测试用JWT认证参数,需与Program.cs中的生产配置一致
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = "your-app-issuer",
                        ValidAudience = "your-app-audience",
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-256-bit-secret-key-here"))
                    };
                });
        });
    }

    // 生成测试用JWT Token
    public string GenerateTestToken(string userId = "test-user-id", IEnumerable<string> roles = null)
    {
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, userId),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };

        if (roles != null)
        {
            claims.AddRange(roles.Select(r => new Claim(ClaimTypes.Role, r)));
        }

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-256-bit-secret-key-here"));
        var signingCreds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: "your-app-issuer",
            audience: "your-app-audience",
            claims: claims,
            expires: DateTime.UtcNow.AddHours(1),
            signingCredentials: signingCreds);

        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

2. 在单元测试中集成使用

以xUnit为例,通过IClassFixture注入测试工厂,生成Token后添加到请求头发起测试:

public class ProtectedEndpointTests : IClassFixture<TestWebAppFactory>
{
    private readonly HttpClient _httpClient;
    private readonly TestWebAppFactory _testFactory;

    public ProtectedEndpointTests(TestWebAppFactory testFactory)
    {
        _testFactory = testFactory;
        _httpClient = testFactory.CreateClient();
    }

    [Fact]
    public async Task Get_ProtectedApi_ReturnsOk_WithValidToken()
    {
        // 生成带Admin角色的测试Token
        var authToken = _testFactory.GenerateTestToken(roles: new[] { "Admin" });
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);

        // 请求受保护端点
        var response = await _httpClient.GetAsync("/api/protected/data");

        // 断言结果
        response.EnsureSuccessStatusCode();
        var responseContent = await response.Content.ReadAsStringAsync();
        Assert.Contains("valid-data", responseContent);
    }

    [Fact]
    public async Task Get_ProtectedApi_ReturnsUnauthorized_WithoutToken()
    {
        var response = await _httpClient.GetAsync("/api/protected/data");
        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
    }
}

核心注意事项

  • 测试环境的JWT参数(密钥、issuer、audience)必须与Program.cs中的生产配置完全一致,否则Token会验证失败
  • 若API依赖其他服务(如数据库),可在ConfigureWebHost中继续替换为内存实现,不影响认证逻辑
  • 全程基于.NET 6原生Top-level statements架构,无需恢复Startup.cs

内容的提问来源于stack exchange,提问作者Terry H

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:06:17