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

[Bug] WithClientName doesn't send the x-app-header unless WithLogging is called. #4979

Open
craigb opened this issue Oct 29, 2024 · 0 comments
Labels
confidential-client needs attention Delete label after triage untriaged Do not delete. Needed for Automation

Comments

@craigb
Copy link

craigb commented Oct 29, 2024

Library version used

4.65.0

.NET version

NET8.0, but can repro in NET6, NET472, and NET48

Scenario

ConfidentialClient - service to service (AcquireTokenForClient)

Is this a new or an existing app?

This is a new app or experiment

Issue description and reproduction steps

Onboarding to use MSI from within my RP. A recommendation from MIRP team is to use .WithClientName("MSI.<RP namespace>"). Using a custom HttpClientFactory, I can see that the request doesn't contain x-app-name header as documented. I can send my own headers in the token request as a workaround, so it's not a huge deal.

However, looking into it further, it appears that the header is dependent on the logger:

_headers.Add(OAuth2Header.AppName, requestContext.Logger.ClientName);
. Simply calling .WithLogging(NullIdentityModelLogger.Instance) fixes the issue, and the request to the authority has the header properly populated.

This seems like a bug. It's certainly unexpected behavior.

Relevant code snippets

var app = ConfidentialClientApplicationBuilder
                .Create(metadata.ClientId.ToString())
                .WithTenantId(metadata.TenantId.ToString())
                .WithCertificate(certificate, sendX5C: true)
                .WithAuthority(authority, validateAuthority: false)
                .WithInstanceDiscoveryMetadata(regionalDiscoveryMetaData)
                // There appears to be a bug in MSAL.NET where the ClientName is not being sent to the server
                // This seems to happen when WithLogging is not called.
                .WithClientName(ClientName)
                .WithLogging(NullIdentityModelLogger.Instance) // <-- the fix to send client name
                .WithHttpClientFactory(MockHttpClientFactory.WithVerification(AssertMethod));

var token = await credential.GetTokenAsync(new TokenRequestContext([$"https://{Guid.NewGuid()}.local/.default"]), CancellationToken.None);

void AssertMethod(HttpRequestMessage request, HttpResponseMessage response)
{
    request.Headers.Should().ContainKey("x-app-name").WhoseValue.Should().Contain("MSI.Microsoft.Experimentation");
}

Expected behavior

Setting .WithClientName() on the builder should ensure that the client name is sent, regardless of any other calls.

Identity provider

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

Regression

No response

Solution and workarounds

Later in each actual request using the AcquireTokenForClientParameterBuilder call .WithExtraHttpHeaders and set x-app-name to the value.

@craigb craigb added needs attention Delete label after triage untriaged Do not delete. Needed for Automation labels Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confidential-client needs attention Delete label after triage untriaged Do not delete. Needed for Automation
Projects
None yet
Development

No branches or pull requests

1 participant