In one of our applications we had the following code to fetch a ClientCredentials token from IdentityServer. This access token could then be used to call another API from our backend:
public static class HttpExtensions | |
{ | |
public static async Task HandleToken(this HttpClient client, IHttpContextAccessor httpContextAccessor, string authority, string clientId, string secret, string apiName) | |
{ | |
var accessToken = await httpContextAccessor.HttpContext.GetRefreshTokenAsync(authority, clientId, secret, apiName); | |
client.SetBearerToken(accessToken); | |
} | |
private static async Task<string> GetRefreshTokenAsync(this HttpContext httpContext, string authority, string clientId, string secret, string apiName) | |
{ | |
var discoveryClient = new DiscoveryClient(authority); | |
var disco = await discoveryClient.GetAsync(); | |
if (disco.IsError) throw new Exception(disco.Error); | |
var tokenClient = new TokenClient(disco.TokenEndpoint, clientId, secret); | |
var tokenResponse = await tokenClient.RequestClientCredentialsAsync(apiName); | |
if (!tokenResponse.IsError) return tokenResponse.AccessToken; | |
return null; | |
} | |
} |
After updating the IdentityModel NuGet package to the latest version, we got the following warnings:
|
The current code is using itās own HttpClient instances and as you probably already know there were some problems with the HttpClient. These are fixed in ASP.NET Core 2.2 and therefore the IdentityModel team decided to update their APIās. Letās get rid of these warnings by using the newly available extension methods: |
public static class HttpExtensions | |
{ | |
public static async Task HandleToken(this HttpClient client, string authority, string clientId, string secret, string apiName) | |
{ | |
var accessToken = await client.GetRefreshTokenAsync(authority, clientId, secret, apiName); | |
client.SetBearerToken(accessToken); | |
} | |
private static async Task<string> GetRefreshTokenAsync(this HttpClient client, string authority, string clientId, string secret, string apiName) | |
{ | |
var disco = await client.GetDiscoveryDocumentAsync(authority); | |
if (disco.IsError) throw new Exception(disco.Error); | |
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest | |
{ | |
Address = disco.TokenEndpoint, | |
ClientId = clientId, | |
ClientSecret = secret, | |
Scope=apiName | |
}); | |
if (!tokenResponse.IsError) return tokenResponse.AccessToken; | |
return null; | |
} | |
} |
More information: https://leastprivilege.com/2018/06/18/making-the-identitymodel-client-libraries-httpclientfactory-friendly/