I have to configure HttpClient to automatically pass Windows credentials (company API that I'm calling is using Windows Authentication). So far I was creating HttpClient inside my methods like so:
var credentialsCache = new CredentialCache {{
new Uri("https://localhost"),
"NTLM",
CredentialCache.DefaultNetworkCredentials
}};
var handler = new HttpClientHandler { Credentials = credentialsCache };
var client = new HttpClient(handler);
but since this could lead to socket exhaustion I want to use factory. Therefore inside Startup.cs
I would add HttpClient like so:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddHttpClient();
}
Then I would inject factory into my service via constructor:
public class MyService
{
private readonly IHttpClientFactory clientFactory;
public MyService(IHttpClientFactory clientFactory)
{
this.clientFactory = clientFactory;
}
public async Task MakeHttpRequest()
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost/endpoint");
var client = clientFactory.CreateClient();
var response = await client.SendAsync(request);
// ...
}
}
How can I configure client created this way to use network credentials? Ideally I would like to configure this only once, inside ConfigureServices()
You can use the options pattern to set configuration for how IHttpClientFactory
creates the HttpClient
. You can configure these options in the following ways
Un-named options, these will apply to all instances of HttpClient
that are created by the factory
services.Configure<HttpClientFactoryOptions>(options =>
{
options.HttpMessageHandlerBuilderActions.Add(builder =>
{
var credentialsCache = new CredentialCache {{
new Uri("https://localhost"),
"NTLM",
CredentialCache.DefaultNetworkCredentials
}};
builder.PrimaryHandler = new HttpClientHandler { Credentials = credentialsCache };
});
});
Named options, these only apply to instances of HttpClient
where you pass the name to the CreateClient
method on the factory
services.Configure<HttpClientFactoryOptions>("myclient", options =>
{
options.HttpMessageHandlerBuilderActions.Add(builder =>
{
var credentialsCache = new CredentialCache {{
new Uri("https://localhost"),
"NTLM",
CredentialCache.DefaultNetworkCredentials
}};
builder.PrimaryHandler = new HttpClientHandler { Credentials = credentialsCache };
});
});
To use the named options you would do
var client = clientFactory.CreateClient("myclient");