Skip to content

Authorization code should always be redeemed with MSAL #3631

Description

@scrocquesel-ml150

Microsoft.Identity.Web Library

Microsoft.Identity.Web

Microsoft.Identity.Web version

4.1.0

Web app

Sign-in users

Web API

Not Applicable

Token cache serialization

Not Applicable

Description

I have configured my web application to use SignedAssertionFromManagedIdentity instead of clientSecret and ResponseType=code.
When redeeming the authorization_code on redirection, the app throws the exception

Microsoft.AspNetCore.Authentication.AuthenticationFailureException: An error was encountered while handling the remote login.
 ---> Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: Message contains error: 'invalid_client', error_description: 'AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'. Trace ID: 4fd981cf-1ae9-4f05-9c7b-f0608a8f0700 Correlation ID: eeb1c507-503c-4a69-84d1-42f2f39543cb Timestamp: 2025-11-28 14:53:40Z', error_uri: 'https://login.microsoftonline.com/error?code=7000218'.
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RedeemAuthorizationCodeAsync(OpenIdConnectMessage tokenEndpointRequest)
   at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync()
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

I configured logging level to debug but I don't see relevant traces around the exception that would tell the credential source fails.

With client secret, it works.

My app runs as a docker container inside App Services. The managed identity works ok to retrieve manually an assertion with this endpoint

// add a minimal endpoint, that returns "Hello World!"
app.MapGet("/token", async (ILogger<Program> logger) =>
{
    var fic = new ManagedIdentityClientAssertion("zzz", null, logger);
    var a = await fic.GetSignedAssertionAsync(new Microsoft.Identity.Client.AssertionRequestOptions()
    {
        ClientID = "yyy",
        TokenEndpoint = "https://login.microsoftonline.com/xxx/oauth2/token"
    });
    return a;
});

Reproduction steps

  1. Program.cs
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration);
    var app = builder.Build();
    
    app.MapGet("/protected", () => "Hello").RequireAuthorization(p => p.RequireAuthenticatedUser());
    
    app.Run();
  2. Configuration
{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "xxx",
    "ClientId": "yyy",
    "ResponseType": "code",
    "ClientCredentials": [ 
      {
        "SourceType": "SignedAssertionFromManagedIdentity",
        "ManagedIdentityClientId": "zzz"
      }
    ],
    "CallbackPath": "/signin-oidc"
  }
}
  1. In Entra of tenant Id xxx, create an app registration, declare a FIC with the managed identity zzz. This app registration has a client id yyy.

Error message

No response

Id Web logs

No response

Relevant code snippets

provided above

Regression

No response

Expected behavior

I would expect a more meaningfull exception, or at least some traces. With subscribeToOpenIdConnectMiddlewareDiagnosticsEvents set to true, I do have traces from category Microsoft.Identity.Web but not useful. Otherwise, I don't see any traces from this category.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions