-
Notifications
You must be signed in to change notification settings - Fork 375
Description
Library version used
4.61.1
.NET version
.NET 8
Scenario
ConfidentialClient - service to service (AcquireTokenForClient)
Is this a new or an existing app?
The app is in production, and I have upgraded to a new version of MSAL
Issue description and reproduction steps
We had an auto-upgrade of Microsoft.Identity.Client
from 4.61.0 to 4.61.1 with renovate. Suddenly, our API Token Acquisition did not work anymore. We get the Exception.
System.TypeLoadException: Could not load type 'Microsoft.Identity.Client.Extensibility.AcquireTokenForClientBuilderExtensions' from assembly 'Microsoft.Identity.Client, Version=4.61.1.0, Culture=neutral, PublicKeyToken=0a613f4dd989e8ae'.
at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForAppAsync(String scope, String authenticationScheme, String tenant, TokenAcquisitionOptions tokenAcquisitionOptions)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForAppAsync(String scope, String authenticationScheme, String tenant, TokenAcquisitionOptions tokenAcquisitionOptions)
at Microsoft.Identity.Web.TokenAcquisition.GetAccessTokenForAppAsync(String scope, String authenticationScheme, String tenant, TokenAcquisitionOptions tokenAcquisitionOptions)
at Carmen.Position.Infrastructure.ExternalServices.DownstreamApiTokenAcquisitionHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /home/vsts/work/1/s/backend/src/Infrastructure/ExternalServices/DownstreamApiTokenAcquisitionHandler.cs:line 10
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.g__Core|5_0(HttpRequestMessage request, Boolean useAsync, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Carmen.Position.Infrastructure.EmtInterface.Repository.EmtAuctionResultServiceClient.<>c__DisplayClass2_0.<b__0>d.MoveNext() in /home/vsts/work/1/s/backend/src/Infrastructure/EmtInterface/Repository/EmtAuctionResultServiceClient.cs:line 27
Relevant code snippets
Our Token Aquisition
#
public class DownstreamApiTokenAcquisitionHandler(ITokenAcquisition acquisition, string appScope) : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var accessToken = await acquisition.GetAccessTokenForAppAsync(appScope);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
return await base.SendAsync(request, cancellationToken);
}
}
Handler registration
public static IHttpClientBuilder AddDownstreamApiTokenAcquisitionHandler(this IHttpClientBuilder builder, Func<IServiceProvider, string> appScopeFunc)
{
return builder.AddHttpMessageHandler(
provider =>
{
var appScope = appScopeFunc(provider);
return ActivatorUtilities.CreateInstance<DownstreamApiTokenAcquisitionHandler>(provider, appScope);
});
}
Together with HttpClientFactory
services.AddHttpClient<TInterface, TClient>(
(serviceProvider, client) =>
{
var optionsFactory = serviceProvider.GetRequiredService<IOptionsMonitor<DownstreamApiOptions>>();
var options = optionsFactory.Get(serviceName);
client.BaseAddress = new Uri(options.BaseUrl!);
})
.AddDownstreamApiTokenAcquisitionHandler(
provider =>
{
var optionsFactory = provider.GetRequiredService<IOptionsMonitor<DownstreamApiOptions>>();
var options = optionsFactory.Get(serviceName);
var appScope = options.Scopes?.SingleOrDefault(s => s.StartsWith("api://", StringComparison.Ordinal));
return appScope ?? throw new InvalidOperationException($"Missing a api//* Scope for {serviceName}");
})
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { UseProxy = false });
### Expected behavior
Just work as in 4.61.0.... or find the problem
### Identity provider
Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)
### Regression
4.61.0
### Solution and workarounds
Downgrade to 4.61.0 resolved the problem.