AzureAD / microsoft-authentication-library-for-dotnet

Microsoft Authentication Library (MSAL) for .NET
https://aka.ms/msal-net
MIT License
1.39k stars 340 forks source link

[Bug] WAM can't be used when requesting token for itself #4667

Open marionoack opened 7 months ago

marionoack commented 7 months ago

Library version used

4.59

.NET version

Windows 11, Net 4.8, x64

Scenario

PublicClient - desktop app

Is this a new or an existing app?

This is a new app or experiment

Issue description and reproduction steps

Hello,

I create in Entra a simple application registration and configure redirect for desktop apps. Then I define an application ID Uri and expose one scope (user and admin consent) Then I add this scope into the API permissions for this app (no pre-consent).

If I try to acquire a token, I received the following error:

Fehlercode: CAA20002 Korrelations-ID: 13a2227f-xxxx-4726-b98c-f5144a5fb091 Zeitstempel: 2024-03-18T08:26:12Z Weitere Informationen: https://www.microsoft.com/wamerrors Servermeldung: AADSTS90009: Application '28c3605d-xxxx-4180-8dac- e3ed534b93f3'(28c3605d-xxxx-4180-8dac-e3ed534b93f3) is requesting a token for itself. This scenario is supported only if resource is specified using the GUID based App Identifier. Trace ID: 0d0a3d5f-xxxx-4726-b775-e411dbdc0200 Correlation ID: 13a2227f-xxxx-4726-b98c-f5144a5fb091 Timestamp: 2024-03- 18 08:26:12Z

Then I removed "WithBroker" to use browser based login. All works fine, I receive a token.

Relevant code snippets

publicClientApp = PublicClientApplicationBuilder.Create(ClientId)
                      .WithDefaultRedirectUri()
                      .WithAuthority(AzureCloudInstance.AzurePublic, Tenant)
                      .WithParentActivityOrWindow(()=>window)
                      .WithBroker(new BrokerOptions(BrokerOptions.OperatingSystems.Windows))
                      .Build();
..
publicClientApp.AcquireTokenInteractive(listOfScopesToRequest)

Expected behavior

Login with or without broker should returns the same result. The error message is not helpful (and wrong?)

Identity provider

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

Regression

No response

Solution and workarounds

Adding the scope in Authorized client application fix the problem.

bgavrilMS commented 7 months ago

If I understand correctly, you have a setup where the client needs to call a web api. You represented both using the same app registration. I believe WAM doesn't support this, and you'll need to create a separate app registration for your web api. Please try that.

marionoack commented 7 months ago

We try to authenticate and authorize only our app. Later on, this app-registration can add external scopes. But for today we use scope/token only for validation purpose of user account. So we see no need to register two applications (app and api) for one application.

If we disable the broker, it works! So we think, the broker has a problem.

Is there a better approach to use application registration for login purpose of a simple app?

bgavrilMS commented 7 months ago

I agree @marionoack - this is a bug in the broker. However, I don't think this is a broker bug that will get fixed anytime soon.

To me, the security benefits that the broker providers outweigh maintaining 2 app registrations (one for client, one for web api).

It's really up to you - use browser based authN and 1 app reg or broker based authN and 2 app reg.

localden commented 3 months ago

@marionoack - have you configured your app registration with the broker-specific redirect URI?

rayluo commented 3 months ago

We try to authenticate and authorize only our app. Later on, this app-registration can add external scopes. But for today we use scope/token only for validation purpose of user account. So we see no need to register two applications (app and api) for one application.

Sounds like @marionoack needs only user authentication (i.e., sign-in), and does not yet need to access a real API. In this case, you may simply use User.Read as a placeholder, and your app only cares about consuming the authentication artifact - an ID token.

bgavrilMS commented 3 months ago

Agreed. I believe you can even skip "User.Read", just set the scopes to an empty array. MSAL will automatically add openid, profile and offline_access. You'll probably still get an access token for scope "User.Read", I am not sure.

MSAL is really a library used to maintain access tokens, for calling downstream APIs. Just logging in users is not a scenario that we optimized for.

rayluo commented 3 months ago

Agreed. I believe you can even skip "User.Read", just set the scopes to an empty array. MSAL will automatically add openid, profile and offline_access. You'll probably still get an access token for scope "User.Read", I am not sure.

For what it's worth, I actually tried that yesterday. The scope-less approach works fine for a sign-in only scenario, and our Python web app (i.e. confidential client) samples have been using that pattern for a while now. The result is an ID token that expectedly contains human-readable "username" and/or "preferred_username", etc.. However, the same pattern with a public client somehow only yields an ID token with no human-readable claims. I had to add "User.Read" as a placeholder. It looks like an eSTS behavior and I don't know why that is the case.

This issue's reporter was using "desktop apps", so I mentioned the "User.Read" placeholder casually. Now that you know the full story. :-)

bgavrilMS commented 3 months ago

That is strange. WAM is supposed to return v1 ID token. What do you mean by "non human readable" claims?

rayluo commented 3 months ago

That is strange. WAM is supposed to return v1 ID token. What do you mean by "non human readable" claims?

Oh, my recent experiment was done on a machine without broker, so, it was the eSTS in system browser experience. Regardless, the high-level takeaway is that "an app that wants only sign-in shall just consume its ID token, without registering another app as an API".

The "no human readable claims" means the ID token does NOT contain "username" claim nor "preferred_username" claim, even when profile scope was used by MSAL. A strange behavior indeed. Could be a bug on the Identity Provider.