Currenty I'm building a solution which is basically an integration between multiple external REST services. Since the solution is having multiple external service, I want to use the .NET ClientFactory to create HttpClients whenever they are wanted. Unfortunately an HttpClient instance created from the ClientFactory always results in an Unauthorized. This is a bit strange since directly creating a new HttpClient results in a success. I red the Microsoft documentation about the HttpClientFactory to determine the differences and possible use cases.
I compared the two different HttpClient instances by extracting the entire objects and did a meld comparison without any differences. Also with postman the call to the service succeeds.
The code which extracts and creates the HttpClient instance (which fails) looks like this:
Program.cs
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; services.AddHttpClient("ClientName", client => { client.BaseAddress = new Uri("https://my.domain.com"); var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes("username:password")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); });TicketRepository.cs
public class TicketsRepository( IHttpClientFactory _httpClientFactory) : ITicketsRepository{ private readonly HttpClient _httpClient = _httpClientFactory.CreateClient("ClientName"); public async Task<Tickets> GetTicketByNumber( int ticket, CancellationToken cancellationToken) { HttpResponseMessage response = await _httpClient.GetAsync( $"{Constants.TicketsUrlTemplate}/{ticket}", cancellationToken); if (!response.IsSuccessStatusCode) { _logger.LogError("Could not successfully retrieve data. Invalid response data is: {response}", response.ToString()); throw new HttpRequestException($"Server did not respond with an http response status 200: {response}"); } return new Tickets(); }}The code which creates an HttpClient instance on every method call and succeeds extracting data looks like this:
public async Task GetTicketByNumber( int ticket, CancellationToken cancellationToken){ using (HttpClient client = new HttpClient()) { client.BaseAddress = new Uri("https://my.domain.com"); var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes("username:password")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); try { HttpResponseMessage response = await client.GetAsync($"/urlTemplate/{ticket}/", cancellationToken); string responseContent = await response.Content.ReadAsStringAsync(); Console.WriteLine("Response Content: " + responseContent); } catch (HttpRequestException e) { Console.WriteLine("Request error: " + e.Message); } }}I did a blank comparison with the Response Objects and HttpClient Objects with identical headers, version, host etc... I must have overlooked something stupid since the ClientFactory works for other Rest Services configured on startup. It is hard to monitor stuf on the server side, since I do not have any physical acccess towards that REST Service, nor do I have access to the source of it. Hopefully someone can point me in the right direction.