WebApplicationFactory 的模拟身份验证不起作用

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)

我也尝试过暂时从启动类中删除身份验证,但看不到任何效果。

有人可以帮助理解为什么嘲笑在这里不起作用吗?

我还可以检查或尝试什么才能正确模拟身份验证?

Igo*_*vas 1

在寻找解决方案时,我遇到了这个相关问题

尽管不完全是我的用例,但我得到了有关缺少授权的提示。所以我通过以下方式创建了网络应用程序工厂:

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 进行调试。示例存储库现已更新