J'ai une application très simple avec un contrôleur authentifié JWT:
[ApiController]
[Authorize]
[Route("[controller]")]
public class JwtController : ControllerBase
{
public JwtController() { }
[HttpGet]
public ActionResult Get() => Ok("Working!");
}
Avec l'authentification configurée comme:
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false
};
});
Pendant les tests, je veux que l'utilisateur soit "authentifié" tout le temps afin que [Authorize] soit ignoré.
[Fact]
public async Task JwtIsSkipped()
{
var response = (await _Client.GetAsync("/jwt")).EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
Assert.Equal("Working!", stringResponse);
}
Exécuter le test comme celui-ci échouera, donc après ce document j'ai ajouté ce simple gestionnaire d'authentification:
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
public const string DefaultScheme = "Test";
public TestAuthHandler(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, "Test user") };
var identity = new ClaimsIdentity(claims, DefaultScheme);
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, DefaultScheme);
return Task.FromResult(AuthenticateResult.Success(ticket));
}
}
Alors maintenant, ma classe de test ressemble à ceci:
public class UnitTest : IClassFixture<WebApplicationFactory<Startup>>
{
private readonly WebApplicationFactory<Startup> _Factory;
private readonly HttpClient _Client;
public UnitTest(WebApplicationFactory<Startup> factory)
{
_Factory = factory;
_Client = _Factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
services.AddAuthentication(TestAuthHandler.DefaultScheme)
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
TestAuthHandler.DefaultScheme, options => { });
});
}).CreateClient();
_Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(TestAuthHandler.DefaultScheme);
}
[Fact]
public async Task JwtIsSkipped()
{
var response = (await _Client.GetAsync("/jwt")).EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
Assert.Equal("Working!", stringResponse);
}
}
Et ça échoue toujours, je n'ai aucune idée de ce que je fais de mal.
Vous devez définir DefaultAuthenticateScheme
builder.ConfigureTestServices(services =>
{
services.AddAuthentication(options =>
{
x.DefaultAuthenticateScheme = TestAuthHandler.DefaultScheme;
x.DefaultScheme = TestAuthHandler.DefaultScheme;
}).AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
TestAuthHandler.DefaultScheme, options => { });
});