My need is to get a HttpClient injected and ready for use right away. But the caveat is that HttpClient needs to have Authorization
header set, and for that I need to make one more call, getting the token.
I managed to do all that configuration in the startup's RegisterServices, but I doubt if it is a good idea.
services.AddHttpClient("OidcClient", (isp, client) =>
{
var options = isp.GetRequiredService<IOptions<MyConfig>>().Value;
client.BaseAddress = new Uri(options.OidcUrl);
});
services.AddHttpClient("MyClient", (isp, client) =>
{
var options = isp.GetRequiredService<IOptions<MyConfig>>().Value;
var oidcClient = isp.GetRequiredService<IHttpClientFactory>().CreateClient("OidcClient");
var data = new Dictionary<string, string>
{
{"client_id", options.ClientId},
{"client_secret", options.ClientSecret}
};
var request = new HttpRequestMessage(HttpMethod.Post, "/connect/token") { Content = new FormUrlEncodedContent(data) };
var response = oidcClient.SendAsync(request).Result;
var token = response.Content.ReadFromJsonAsync<TokenResponse>().Result;
client.BaseAddress = new Uri(options.Url);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);
});
Then it is properly injected into my code and I'm able to use the client with the authorization header.
So, my concerns are:
.Result
for an asynchronous call, is there an alternative?And the main question: is it a 'good idea' to make dependency calls inside DI configuration?
Although the CodeCasters answer is very correct. Ideally you would use a delegating handler for this task.
It allows you to intercept the request at various stages and add whatever artefacts are needed in the request, in your case authorisation attributes, It is also async friendly.
However take care of errors and what you return to caller. lest there be no surprises for a consumer