I am trying to connect my api service (.net core) to identity (.net core + identityserver4) and I am getting this error message
System.InvalidOperationException: IDX20803: Unable to obtain configuration from...
that's because the identity discovery endpoint expects an additional custom header. I created custom IDocumentRetriever
public class AppHttpDocumentRetriever : HttpDocumentRetriever, IDocumentRetriever
and registered it in Startup
services.AddTransient<IDocumentRetriever, AppHttpDocumentRetriever>();
but it doesn't inject in ConfigurationManager. I don't want to add this custom header to all outbound requests via custom middleware. Are there other approaches to adding a custom header to request to the discovery endpoint?
All requests made in the background are performed using HttpClient. What you can do is inject a HttpMessageHandler into the HttpClient.
To set your own handler, you can set the BackchannelHttpHandler property.
like:
.AddOpenIdConnect(options =>
{
options.BackchannelHttpHandler = new BackChannelListener();
....
}
A sample handler that logs the requests is shown below and from that I am sure you can figure out how to add a custom header on the outgoing request.
namespace Infrastructure
{
/// <summary>
/// Backchannel listener, that will log requests made to our IdentityServer
/// Source: IdentityServer in Production training class https://www.tn-data.se
/// </summary>
public class BackChannelListener : DelegatingHandler
{
public BackChannelListener() : base(new HttpClientHandler())
{
Console.WriteLine();
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Console.WriteLine("BackChannelListener");
Console.WriteLine("@@@@ SendASync: " + request.RequestUri);
var sw = new Stopwatch();
sw.Start();
var result = base.SendAsync(request, cancellationToken);
result.ContinueWith(t =>
{
sw.Stop();
Console.WriteLine("@@@@ success: " + result.IsFaulted);
Console.WriteLine("@@@@ loadtime: " + sw.ElapsedMilliseconds.ToString());
Console.WriteLine("@@@@ url: " + request.RequestUri);
Serilog.Log.Logger.ForContext("SourceContext", "BackChannelListener")
.ForContext("url", request.RequestUri)
.ForContext("loadtime", sw.ElapsedMilliseconds.ToString() + " ms")
.ForContext("success", result.IsCompletedSuccessfully)
.Information("Loading IdentityServer configuration");
});
return result;
}
}
}