I have an ASP.Net Core application configured to issue and authenticate JWT bearer tokens. Clients are able to successfully retrieve bearer tokens and authenticate with the token when the site is hosted in Kestrel.
I also have a suite of integration tests which use Microsoft.AspNetCore.TestHost.TestServer. Prior to adding authentication, the tests were able to successfully make requests against the application. After adding authentication, I started getting errors pertaining to accessing open id configuration. The specific exception I'm seeing is this:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://
fail: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[3]
Exception occurred while processing message.
System.InvalidOperationException: IDX10803: Unable to obtain configuration from: 'http://localhost/.well-known/openid-configuration'. ---> System.IO.IOException: IDX10804: Unable to retrieve document from: 'http://localhost/.well-known/openid-configuration'. ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found).
Based on my research, this is sometimes triggered when the Authority is set to a different host than the hosting server. For instance, Kestrel runs at http://localhost:5000 by default which is what I had my Authority set to initially, but upon setting it to what the TestServer is emulating (http://localhost), it still gives the same error. Here is my authentication configuration:
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
RequireHttpsMetadata = false,
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateAudience = true
},
Audience = "Anything",
Authority = "http://localhost"
});
What is odd is that attempting to hit the URL directly from the Integration test works fine:
So how do you configure the ASP.Net TestServer and OpenId Connect infrastructure to work together?
=== EDIT ====
In reflecting on this a bit, it occurred to me that the issue is that the JWT authorization internals is trying to make a request to http://localhost port 80, but it isn't trying to make the request using the TestServer and is therefore looking for a real server. Since there isn't one, it's never going to authenticate. It looks like the next step is to see if there is some way to turn off the Authority check or extend the infrastructure in some way to allow for it to use the TestServer as the host.