If you are building integration tests for ASP.NET WebAPIs using Microsoft's WebApplicationFactory and your API is secured with JWT bearer authentication, then at some point you'll probably want to mock the JWT authentication mechanism. Of course, you always have the option of including the "real" JWT issuer in the scope of your tests, but it can get quite tricky to automate the security checks of real IDPs! The first step is to create a class that will handle issuing the "fake" JWT tokens:

public static class MockJwtTokens
{
    public static string Issuer { get; } = Guid.NewGuid().ToString(); // random issuer
    public static SecurityKey SecurityKey { get; }
    public static SigningCredentials SigningCredentials { get; }

    private static readonly JwtSecurityTokenHandler TokenHandler = new();
    private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create();
    private static readonly byte[] Key = new byte[32];

    static MockJwtTokens()
    {
        Rng.GetBytes(Key);
        SecurityKey = new SymmetricSecurityKey(Key) { KeyId = Guid.NewGuid().ToString() };
        SigningCredentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256);
    }

    public static string GenerateJwtToken(IEnumerable<Claim> claims)
    {
        return TokenHandler.WriteToken(new JwtSecurityToken(Issuer, "YOUR-EXPECTED-AUDIENCE", claims, null, DateTime.UtcNow.AddMinutes(20), SigningCredentials));
    }
}
NOTE: If you validate the "audience" field in your system, then ensure the audience is set as you'd expect. The 2nd step is to replace the configuration of the SUT (system under test) to start trusting your "fake" issuer instead of the real one:

public class WebTestFixture() : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        base.ConfigureWebHost(builder);

        builder.ConfigureTestServices(services =>
        {
            services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                var config = new OpenIdConnectConfiguration()
                {
                    Issuer = MockJwtTokens.Issuer
                };

                config.SigningKeys.Add(MockJwtTokens.SecurityKey);
                options.Configuration = config;
            });
        });
    }
}
With that in place, you simply need to add the token with claims of your choice to your fixture's HttpClient. For example to add a token with an "email" claim:

// extension method for adding an email claim JWT
public static HttpClient WithUserCredentials(this HttpClient client, string jwtEmail)
{
    if (string.IsNullOrEmpty(jwtEmail))
    {
        return client;
    }

    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",
        MockJwtTokens.GenerateJwtToken([
            new Claim("email", jwtEmail)
        ]));

    return client;
}

// example usage
using var client = fixture.CreateClient().WithUserCredentials(theEmail);
Using extension methods is optional, structure it however you like and include as many claims as is required for your test scenario.