I have an app that uses MSAL to obtain an access token from Azure AD. This is done on the client side which has it's own Azure App Registry. I then pass this access token to the server, which then calls Microsoft Graph to obtain other information on behalf of the user. However, I get an audience does not match failure when I make the graph call. This seems appropriate, but now I'm not sure how to add the web server audience id to the token.
First, is this the correct workflow for this type of scenario? I'm using MSAL to authenticate the user, then using the web service to make the call to graph for more info. Second, is it possible to add multiple audiences to the access token if using AzureADBearer? I know it's possible with the JWTBearer.
//web service
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddAzureAdBearer(options =>
{
Configuration.Bind("AzureAd", options);
})
.AddCookie(options => options.Cookie.SameSite = SameSiteMode.None);
Concept
The way you're describing your flow it looks like you are using the the token coming from client to webservice directly for calling Microsoft Graph API on behalf of user.. this would not be correct on behalf of flow.
Once you have authenticated the client in web service based on incoming token, then web service is supposed to acquire a new token specifically for Microsoft graph on behalf of user (making use of the first token).
See more detailed description of the flow here Azure Active Directory v2.0 and OAuth 2.0 On-Behalf-Of flow
Code Sample
Take a look at this code sample. It's very close to what you are trying to achieve.
Here a WPF app first calls ASP.NET Core Web API, and the API later calls Microsoft Graph on behalf of user.
ASP.NET Core 2.1 Web API calling Microsoft Graph, itself called from a WPF application using Azure AD V2
Important parts to notice from code:
Look at TodoListController.cs where the API first gets a new AccessToken on behalf of the user, passing in required scopes and then uses this new token to make a call to Microsoft Graph API.
public async Task<string> CallGraphApiOnBehalfOfUser()
{
string[] scopes = { "user.read" };
// we use MSAL.NET to get a token to call the API On Behalf Of the current user
try
{
string accessToken = await _tokenAcquisition.GetAccessTokenOnBehalfOfUser(HttpContext, scopes);
dynamic me = await CallGraphApiOnBehalfOfUser(accessToken);
return me.userPrincipalName;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With