Configure HttpClient to use a service to populate the authentication header?

Viewed 1050

I want to use a typed HTTP client so I register it like this in the ServiceCollection

services.AddHttpClient<ApiService>();

All the requests that the client makes, must be authenticated. So I'd need to slightly modify the snippet above to this:

services.AddHttpClient<ApiService>(c =>
{
    c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "");
});

The bearer token needs to be renewed all 5 minutes, so I need to create service that needs dependencies like an HttpClient (to authenticate and get the token) and a MemoryCache (to store the token as long it's valid).

The problem is, as you can see, this is still in the phase before the service provider is built, so I can't resolve anything at this point... What are my options here?

2 Answers

You can access the ServiceProvider like this:

services.AddHttpClient<ApiService>(provider, c) =>
{
    var token = provider.GetRequiredService<MyTokenService>().GetToken();
    c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
});

If you don't have access to the overload with the provider you will need to update your dependencies. AddHttpClient will register a transient client so the func ("factory method") will run each time you inject it somewhere.

Could you do this in the constructor of ApiService, also passing the authentication service to that via DI?

e.g.

public class ApiService
{
    private readonly HttpClient client;

    public ApiService(HttpClient client, IAuthenticationService auth)
    {
        // configure client here

        this.client = client;
    }
}
Related