Skip to content

[Bug] MsalClientException raised when token_type is set to pop for AtPop #5203

@sruke

Description

@sruke

Library version used

4.70.0

.NET version

.NET 9.0

Scenario

ConfidentialClient - web api (AcquireTokenOnBehalfOf)

Is this a new or an existing app?

None

Issue description and reproduction steps

Issue: Microsoft.Identity.Web is being updated to support FIC with AtPop. This update changes the body parameters sent in the HttpRequest to acquire a token on behalf of the Web API:

client_assertion: Now contains the signed assertion (managed identity or custom assertion provided by the customer).
req_cnf: Base64 URL encoded JWK.
token_type: pop.

Due to these changes, an MsalClientException is raised with the error: "Microsoft.Identity.Client.MsalClientException: You asked for token type Bearer, but received pop. This occurs if the Identity Provider (AAD, B2C, ADFS, etc.) does not support the requested token type. If using ADFS, consider upgrading to the latest version."

Stack Trace:
TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken) RequestBase.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, CancellationToken cancellationToken)
ClientCredentialRequest.GetAccessTokenAsync(CancellationToken cancellationToken, ILoggerAdapter logger)
ClientCredentialRequest.ExecuteAsync(CancellationToken cancellationToken)
<b__1>d.MoveNext()
--- End of stack trace from previous location ---
StopwatchService.MeasureCodeBlockAsync(Func`1 codeBlock)
RequestBase.RunAsync(CancellationToken cancellationToken)
ConfidentialClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenForClientParameters clientParameters, CancellationToken cancellationToken)
TokenAcquisition.GetAuthenticationResultForAppAsync(String scope, String authenticationScheme, String tenant, TokenAcquisitionOptions tokenAcquisitionOptions) line 600
ITokenAcquirer.GetTokenForAppAsync(String scope, AcquireTokenOptions tokenAcquisitionOptions, CancellationToken cancellationToken) line 54
TokenAcquirer.AcquireTokenWithMs10AtPop_ClientCredentialsAsync() line 397

Top branch in Identity.Web: sruthi/AtPop
Running AcquireTokenWithMs10AtPop_ClientCredentialsAsync test fails.

Relevant code snippets

public async Task AcquireTokenWithMs10AtPop_ClientCredentialsAsync()
{
    TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest();
    TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
    IServiceCollection services = tokenAcquirerFactory.Services;

    services.Configure<MicrosoftIdentityApplicationOptions>(s_optionName, option =>
    {
        option.Instance = "https://login.microsoftonline.com/";
        option.TenantId = "msidlab4.onmicrosoft.com";
        option.ClientId = "f6b698c0-140c-448f-8155-4aa9bf77ceba";
        option.ClientCredentials = s_clientCredentials;
    });

    services.AddInMemoryTokenCaches();
    var serviceProvider = tokenAcquirerFactory.Build();
    var options = serviceProvider.GetRequiredService<IOptionsMonitor<MicrosoftIdentityApplicationOptions>>().Get(s_optionName);
    var credentialsLoader = serviceProvider.GetRequiredService<ICredentialsLoader>();
    await credentialsLoader.LoadCredentialsIfNeededAsync(options.ClientCredentials!.First());
    var cert = options.ClientCredentials!.First().Certificate;

    // Get the token acquisition service
    ITokenAcquirer tokenAcquirer = tokenAcquirerFactory.GetTokenAcquirer(s_optionName);
    RsaSecurityKey rsaSecurityKey = CreateRsaSecurityKey();
    var result = await tokenAcquirer.GetTokenForAppAsync("https://graph.microsoft.com/.default",
           new TokenAcquisitionOptions()
           {
               PopPublicKey = rsaSecurityKey.KeyId,
               PopClaim = CreatePopClaim(rsaSecurityKey, SecurityAlgorithms.RsaSha256)
           });
    Assert.NotNull(result.AccessToken);
}

Expected behavior

Pop token as an app token is accepted

Identity provider

Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)

Regression

No response

Solution and workarounds

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions