4

I have an OpenIdDict authentication server which is based on AspNet.Security.OpenIdConnect.Server. The setup works as expected.

Now to do some in process integration;system tests which span the whole backend architecture I use the TestServer class.

Why I test like this is another question

  • Most test code coverage with least amount of work
  • It has been decided to not do unit tests... (too much work they say)
  • Real integration tests which span much less code where also seen as to much work when I want to achieve a good coverage
  • The test are based on an framework that is build using a domain language approach which means I can describe functionality the same for our current web api tests, for selenium web ui tests, for selenium load tests and for wpf ui testing.

When I call an web api endpoint of my ressource server the authorization wants to load http://localhost/.well-known/openid-configuration but fails.

{"IDX10803: Unable to obtain configuration from: 'http://localhost/.well-known/openid-configuration'."})

This are the OpenIdConnectSettings I use for the Testing Environment:

  • AllowInsecureHttp = true,
  • RequireHttpsMetadata = false

Can I get the server to emit the configuration or can I provide the configuration in an other way?

Kévin Chalet
  • 39,509
  • 7
  • 121
  • 131
NtFreX
  • 10,379
  • 2
  • 43
  • 63

1 Answers1

4

What's important to note with TestServer is that everything happens in memory: no socket is open to handle the HTTP requests your application might send.

Unfortunately, the OpenID Connect client middleware (that uses HttpClient internally) has no way to know that and tries to send a "real" HTTP request to OpenIddict to retrieve the discovery document.

To work around this issue, the recommended approach is to replace the default backchannel handler used by the OIDC middleware to use the in-memory handler provided by TestServer.CreateHandler():

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    Authority = "http://localhost:54540/",
    RequireHttpsMetadata = false,
    ClientId = "myClient",
    ClientSecret = "secret_secret_secret",
    BackchannelHttpHandler = server.CreateHandler()
});

Note: the same approach also applies to the JWT bearer middleware and the aspnet-contrib introspection middleware.

Kévin Chalet
  • 39,509
  • 7
  • 121
  • 131
  • It may be very difficult for me to implement it like this as in my architecture the authentication server and the ressource server are the same. Thats why I do not have a TestHost instance of the authentication server when I setup the ressource server. I don't think openiddict is intented to be used in this way so I have to pay the price. But thanks a lot for your answer! – NtFreX Mar 23 '17 at 09:24
  • 2
    @Dr.Fre actually, it has nothing to do with OpenIddict since it's a client-side issue (it would work **exactly the same way** with any other provider). If you really don't want to split your pipeline, consider using a real integration testing environment, with a real server. This project from the ASP.NET team (not available on NuGet.org), might help you with that: https://github.com/aspnet/Hosting/tree/1.0.0/src/Microsoft.AspNetCore.Server.Testing. You can see it in action in the MusicStore sample: https://github.com/aspnet/MusicStore/tree/1.0.0/test/E2ETests. – Kévin Chalet Mar 23 '17 at 12:59