In this lesson, you will learn how to bypass external identity providers during integration testing by implementing a "fake" authentication handler to authorize your test requests.
When testing protected endpoints with WebApplicationFactory, relying on a real identity provider (like Auth0 or Azure AD) makes tests slow, flaky, and dependent on external network connectivity. Instead, we can inject a custom AuthenticationHandler into our test server that programmatically injects the ClaimsPrincipal we need.
Implementing the Fake Handler
To simulate an authenticated user, create a class that inherits from AuthenticationHandler<AuthenticationSchemeOptions>. This handler will ignore the actual security token and instead force an authentication ticket with pre-defined claims.
public class FakeAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
public FakeAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock) { }
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var claims = new[] { new Claim(ClaimTypes.Name, "TestUser"), new Claim(ClaimTypes.NameIdentifier, "123") };
var identity = new ClaimsIdentity(claims, "Test");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "TestScheme");
return Task.FromResult(AuthenticateResult.Success(ticket));
}
}
Injecting into WebApplicationFactory
Now, configure your WebApplicationFactory to use this handler for the "TestScheme". By overriding the ConfigureWebHost method, you replace the real authentication configuration with your test-specific setup.
var factory = new WebApplicationFactory<Program>().WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddAuthentication("TestScheme")
.AddScheme<AuthenticationSchemeOptions, FakeAuthHandler>("TestScheme", null);
});
});
var client = factory.CreateClient();
// Now, every request made by this client is automatically authenticated as "TestUser"
By using this approach, you effectively mock the authentication layer. Your API controllers will see an authorized User object, allowing you to focus on testing your business logic and authorization policies without the overhead of token validation or external server communication.
Key Takeaway: Use custom AuthenticationHandlers in your integration tests to substitute real identity providers with a deterministic, local authentication flow.