Authentication in ASP.NET Core integration tests fails (401 Unauthorized)

Viewed 396

I am developing a WebDAV interface for our ECM based on the IT HIT WebDAV engine and ASP.NET Core 5.
The WebDAV server should support Basic and Windows authentication.
After the standard authentication middleware I call another custom middleware that does further checks:

Startup.cs:
public void Configure(IApplicationBuilder app)
{
    ...
    app.UseAuthentication();
    app.UseMySpecialAuthenticationValidator();
    ...
}

MySpecialAuthenticationValidator has the following InvokeAsync method:

public async Task InvokeAsync(HttpContext context)
{
    if (!context.Request.Headers.ContainsKey(HeaderNames.Authorization))
    {
        Logger.LogDebug("Unauthorized access - challenge");
        await context.ChallengeAsync();
        return;
    }
    else
    {
        // if sending a request with Postman using Basic auth, IsAuthenticated is true
        // if sending a request from my integration test using Basic auth, IsAuthenticated is false
        if (context.User.Identity.IsAuthenticated)
        {
            // do something useful
            ...
        }
        else
        {
            Logger.LogError("Unauthorized access - User not found");
            context.User = new ClaimsPrincipal();
            context.Response.StatusCode = 401;
            return;
        }

        await Next(context);
    }
}

This is my test class with the only test so far:

public class WebDavTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly HttpClient _HttpClient;
    private string base64EncodedSecret = ...

    public WebDavTests(WebApplicationFactory<Startup> factory)
    {
        this._HttpClient = factory.CreateDefaultClient();
        this._HttpClient.DefaultRequestHeaders.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64EncodedSecret);
    }

    [Fact]
    public async Task Test1()
    {
        var response = await _HttpClient.GetAsync("/testfolder/document.txt");
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}

The test fails with 401 Unauthorized (context.User.Identity.IsAuthenticated is false in the InvokeAsync method of my AuthenticationValidator middleware). Why?
If I send the same Get-Request with Postman, also with Basic Authentication, then it works (i.e. context.User.Identity.IsAuthenticated is true).
I have checked base64EncodedSecret several times, it matches in my test and in the Postman request.

I know that in an integration test the server is not started "normally", but runs "inside the test framework". Does the authentication work differently in this environment? Everything I "googled" was only about APIs with endpoints, controllers and [Authorize] attributes. I don't have any of that here.

I also don't want to "fake" a user for the tests (at least not yet).
I would like to run the integration tests with a "normal" user that exists in the system.

0 Answers
Related