Context
I'm successfully using MSAL to authenticate users against an AD app in an Azure AD
I have a CCA talking to https://login.microsoftonline.com/<tenant> and performing AcquireTokenOnBehalfOfAsync, giving me valid OBO token which works as authorization against graph.windows.net
Note
Some of this question may be better aimed at the Azure team but I hope I can get some response as to whether my expectations are correct
Question
My goal is to use an OBO token to communicate with the Azure resource graph via management.azure.com
In the Azure portal I can add Azure management API user_impersonation as a scope to my application like so:

This is desirable because I want to be able to talk to management.azure.com
What I do not understand is how to actually _consume_ this API
user_impersonation as a scope since it does not workuser_impersonation will be an acceptable scope?)Additionally:
user_impersonation really what I want in this instance? This permission is in preview and the documentation doesn't really explain a lot about it. Is it a good thing to be using or is it, for example, in preview because it's a legacy compatibility measure or something?TLDR
How do I use MSAL to get valid tokens across multiple APIs (e.g. management.azure.com especially) and how does OBO work in this situation? Are OBO tokens API scoped?
@DavidR91
the scopes should be :
scopes = new[] { "https://management.azure.com/user_impersonation" }
For an example on how this is used, please see.
See https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/blob/c34fac62333c3eaac90a9699bdeb16543dd36220/3-WebApp-multi-APIs/Controllers/HomeController.cs#L55-L68
Note that you can also use
scopes = new[] { "https://management.azure.com/.default" }
for more details see Scopes for a Web API accepting v1.0 tokens
@jmprieur thanks for that - that works but I still find that I have to do separate token acquisition calls in order for it to work?
e.g. if I do AcquireTokenOnBehalfOfAsync with scope Group.Read.All, Directory.Read. All, https://management.azure.com/user_impersonation I do get a token, but the token does not contain any management info and is refused by the management endpoint.
Additionally, specifying the scope in this way causes AcquireTokenSilentAsync to error with
AADSTS28000: Provided value for the input parameter scope is not valid because it contains more than one resource. Scope Directory.Read.All Group.Read.All https://management.azure.com/user_impersonation offline_access openid profile is not valid.
If I do the token acquisition calls separately (first for graph resources and then for Azure), everything works and the management endpoint accepts the token
(and the AADSTS28000 makes sense, since doing them separately the aud field of the token is graph* for graph scopes and management.azure.com for Azure scopes, and it's clearly not possible for it to be both of these things at once)
Is this the expected behaviour, or does it point to a misconfiguration somewhere? (Notable that the sample seemingly _is_ able to request both user_impersonation and directory.read.all?)
This is the expected behavior, @DavidR91 : the Microsoft identity platform (formerly Azure AD) v2.0 endpoint allows you to get tokens for only one resource, and here you have two (Graph and ARM). Something you could try is preconsent when you start your Web App (assuming this is a Web App), by adding a bunch of options.Scopes.Add() somewhere like here: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/blob/c34fac62333c3eaac90a9699bdeb16543dd36220/Microsoft.Identity.Web/StartupHelpers.cs#L43
@jmprieur thanks for all your help, I have this flow working properly and the samples you've linked to were extremely useful
@jmprieur - I can understand why this has been done for Microsoft APIs as they exist outside my domain (different AUD) but it seems rather odd that I need to do this when protecting your own APIs inside my domain.
I would not expect to request an Access Token per Resource API (AKA Application in Azure AD). In fact I would to share that access token to across resource APIs in my domain.
As far as I remember, Azure B2C doesn't have this issue and you can request multiple scopes for a single access token.
You can always decide how you want to validate the access token in your Web APIs, @heymega . In particular if you really want to use the same token for all your resources, you can validate the audience of the token accordinly. This would not be done with MSAL.NET though but with the middleware. See token validation
Or are you suggesting having a single resource in Azure AD which contains all the scopes across my services?
Because getting a single Access Token containing scopes across resources doesn't seem supported by Azure AD.
yes, you can also use the same client ID and different scopes if you wish
Or have several client ids, but have a special logic to accept the audience of the tokens in your web APIs