Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression in Microsoft.Windows.Client 4.61.1? - System.TypeLoadException #4789

Closed
DerAlbertCom opened this issue May 28, 2024 · 4 comments · Fixed by #4792
Closed

Regression in Microsoft.Windows.Client 4.61.1? - System.TypeLoadException #4789

DerAlbertCom opened this issue May 28, 2024 · 4 comments · Fixed by #4792

Comments

@DerAlbertCom
Copy link

DerAlbertCom commented May 28, 2024

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.
@DerAlbertCom DerAlbertCom added needs attention Delete label after triage untriaged Do not delete. Needed for Automation labels May 28, 2024
@DerAlbertCom DerAlbertCom changed the title Regression in Microsoft.Windows.Client 4.61.1? - System.TypLoadException Regression in Microsoft.Windows.Client 4.61.1? - System.TypeLoadException May 28, 2024
@bgavrilMS
Copy link
Member

Good catch. It's because of this https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/pull/4758/files

Strictly speaking it's not a build breaking change, but since MSAL is 2 layers down, a break occurs. We will fix this. Please stay on 4.61.0 for now.

@bgavrilMS bgavrilMS added bug P2 breaking change and removed untriaged Do not delete. Needed for Automation needs attention Delete label after triage labels May 28, 2024
@mancyc
Copy link

mancyc commented May 28, 2024

@bgavrilMS is there an ETA for the release with the fix? We're hitting this too.

@bgavrilMS
Copy link
Member

@mancyc @DerAlbertCom - if you remove the explicit dependnecy on MSAL, do you still have problems?

@bgavrilMS bgavrilMS mentioned this issue May 30, 2024
1 task
@mancyc
Copy link

mancyc commented May 30, 2024

Nope, <4.61.1 works fine, so this is not urgent for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants