Igo*_*vas 6 c# authentication .net-core asp.net-core
我们在 .NET 6 WebAPI 集成测试中遇到了一些模拟身份验证问题。
所采用的方法正是Microsoft集成测试指南中描述的方法:
factory = new WebApplicationFactory<Startup>();
var client = factory.WithWebHostBuilder(builder =>
{
builder
.UseTestServer()
.ConfigureTestServices(services =>
{
services.AddAuthentication("Test")
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
"Test", options => {});
});
})
.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false,
});
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Test");
var result = await client.GetAsync($"{client.BaseAddress}/api/mycontroller/{par1}/{par2}");
Run Code Online (Sandbox Code Playgroud)
请注意,模拟的身份验证模式“Test”被设置为客户端授权标头中的默认模式。
这就是身份验证处理程序的定义方式:
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
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, "Test");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "Test");
var result = AuthenticateResult.Success(ticket);
return Task.FromResult(result);
}
}
Run Code Online (Sandbox Code Playgroud)
API 方法具有 [Authorize] 属性,并且可以很好地处理生产客户端代码(默认持有者令牌设置)经过身份验证的请求。
在测试执行时,GetAsync 调用的结果是 302。这是未经身份验证的调用的预期结果,因为在测试设置期间禁用了重定向。
问题是为什么不调用模拟的身份验证处理程序(HandleAuthenticateAsync 方法)?
如果我在 WebAPI 上明确授权“测试”模式,则可以正确调用身份验证。
//[Authorize]
[Authorize(AuthenticationSchemes = "Test")]
Run Code Online (Sandbox Code Playgroud)
我也尝试过暂时从启动类中删除身份验证,但看不到任何效果。
有人可以帮助理解为什么嘲笑在这里不起作用吗?
我还可以检查或尝试什么才能正确模拟身份验证?
在寻找解决方案时,我遇到了这个相关问题。
尽管不完全是我的用例,但我得到了有关缺少授权的提示。所以我通过以下方式创建了网络应用程序工厂:
var client = factory.WithWebHostBuilder(builder =>
{
builder
.UseTestServer()
.ConfigureTestServices(services =>
{
services.AddAuthentication("Test")
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
"Test", options => { });
services.AddAuthorization(opts =>
{
opts.DefaultPolicy = new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes("Test")
.RequireAuthenticatedUser()
.Build();
});
});
})
.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false,
});
Run Code Online (Sandbox Code Playgroud)
这似乎已经足够了。至少我的示例测试用例现在通过了,我可以通过 TestAuthHandler 进行调试。示例存储库现已更新。