Please follow the issue template below. Failure to do so will result in a delay in answering your question.
[email protected] or @azure/[email protected]@azure/[email protected]@azure/[email protected]@azure/[email protected]@azure/[email protected]The documentation for requesting scopes for implicit flow could be improved to clarify that requesting scopes for more than one exposed APIs only returns a token with the passed scopes associated with the same exposed API as the first scope in the array.
My scopes array looked like this:
[ "user.read", "api://<myCustomApiClientId>/My.Scope" ]
The returned access token would only validate against the Graph API scope (user.read) and not my custom API. When I switched the two scopes, it worked for my custom API. As I added more scopes, any time user.read was the first item in the array, it would only issue a token with Graph API scopes.
Upon further reflection, it made sense from a security perspective that a given JWT would not validate against more than one exposed API. I'm still fairly new to identity management with AAD/msal/etc though, so having this in the docs would have saved me an immense amount of time.
@ebsndrs As you observe, access tokens are issued per resource, e.g. you cannot use an access token issued for MS Graph on your custom web API.
During login calls, you can provide scopes that span multiple resources, however, when calling acquireTokenSilent, you need to make separate calls for each set of scopes per resource.
For example:
const graphToken = await msalInstance.acquireTokenSilent({ scopes: [ "user.read" ] });
const customApiToken = await msalInstance.acquireTokenSilent({ scopes: ["api://<myCustomApiClientId>/My.Scope"] });
I agree this isn't as intuitive as it could be, and we could certainly do a better job documenting it, so we'll make sure to do that. Thanks for the feedback!
Most helpful comment
@ebsndrs As you observe, access tokens are issued per resource, e.g. you cannot use an access token issued for MS Graph on your custom web API.
During login calls, you can provide scopes that span multiple resources, however, when calling
acquireTokenSilent, you need to make separate calls for each set of scopes per resource.For example:
I agree this isn't as intuitive as it could be, and we could certainly do a better job documenting it, so we'll make sure to do that. Thanks for the feedback!