How to use ConfigurePrimaryHttpMessageHandler generic
Derive from HttpClientHandler
or any HttpMessageHandler
derived class.
public class MyHttpClientHandler : HttpClientHandler {
public MyHttpClientHandler() {
//Set here whatever you need to get configured
}
//...override members as needed
}
Call your handler using appropriate extension
services
.AddHttpClient<IMyService, MyService>()
.ConfigurePrimaryHttpMessageHandler<MyHttpClientHandler>();
The MyHttpClientHandler
will be resolved from a scoped service provider that shares the lifetime of the handler being constructed.
Manuel Navarro
Updated on June 14, 2022Comments
-
Manuel Navarro almost 2 years
I want to add an HttClientHandler for a Typed HttpClient in order to include certificate authentication.
All the examples I'm finding on the internet are like this:
services.AddHttpClient<IMyService, MyService>() .ConfigurePrimaryHttpMessageHandler(() => { return new HttpClientHandler() { // Set here whatever you need to get configured }; });
But I don't want to include all the logic to obtain the certificate here, so I would like to use the generic version of ConfigurePrimaryHttpMessageHandler<> and write my own message handler to include the certificate in the request.
The problem is that I'm struggling to understand how should I implement the message handler... should I inherit from HttpClientHandler ??
Help, please!
Update
As I initially suspected, and @Nkosi confirmed, to derive from HttpClient handler is the way to go in this scenario. The code in the ends looks similar to this:
public class MyHttpClientHandler : HttpClientHandler { private readonly IMyConfiguration _myConfiguration; public MyHttpClientHandler(IMyConfiguration myConfiguration) { _myConfiguration = myConfiguration; using (var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine)) { certStore.Open(OpenFlags.ReadOnly); var certCollection = certStore.Certificates.Find( X509FindType.FindBySerialNumber, _myConfiguration.MyCertificateSerial, true); X509Certificate2 certificate = certCollection[0]; ClientCertificateOptions = ClientCertificateOption.Manual; SslProtocols = System.Security.Authentication.SslProtocols.Tls12; ClientCertificates.Add(certificate); } } }
Very important!
On the other hand while trying to register my http client handler I noticed it was never being called. After some googling I found out that currently there's an open bug about that (https://github.com/aspnet/Extensions/issues/851). So until it get's fixed you need configure your handler this way:
services.AddTransient<MyHttpClientHandler>(); services.AddHttpClient<IMyService, MyService>() .ConfigurePrimaryHttpMessageHandler(sp => sp.GetRequiredService<MyHttpClientHandler>());
-
Manuel Navarro over 4 yearsPlease refer to the update I added in the original post, as currently there's a bug at configuring primary Http message handlers using the generic version.