I have an application which needs access to a custom API as well as the ability to send emails via the Graphs API. When I get my access token I seem to only be able to pass graphs OR my api scopes but not a combination of both.
I create my app as follows
_clientApp = PublicClientApplicationBuilder.Create(ClientId)
.WithAuthority(AzureCloudInstance.AzurePublic, Tenant)
.Build();
I then authenticate as follows
private async Task<AuthenticationResult> AuthenticateAsync(string[] scopes)
{
string error = String.Empty;
AuthenticationResult authResult = null;
var accounts = await _clientApp.GetAccountsAsync();
var firstAccount = accounts.FirstOrDefault();
try
{
authResult = await _clientApp.AcquireTokenSilent(scopes, firstAccount).ExecuteAsync();
}
catch (MsalUiRequiredException ex)
{
// A MsalUiRequiredException happened on AcquireTokenSilent.
// This indicates you need to call AcquireTokenInteractive to acquire a token
System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");
try
{
authResult = await _clientApp.AcquireTokenInteractive(scopes)
.WithAccount(accounts.FirstOrDefault())
.WithPrompt(Prompt.SelectAccount)
.ExecuteAsync();
}
catch (MsalException msalex)
{
error += $"Error Acquiring Token:{System.Environment.NewLine}{msalex}" + Environment.NewLine;
}
}
catch (Exception ex)
{
error += $"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}" + Environment.NewLine;
}
if (string.IsNullOrEmpty(error))
return authResult;
else
throw new AuthenticationException(error);
}
If I pass the scope
string[] graphsScopes = new string[] { "user.read" };
I can send the email successfully but I cannot make calls to my customAPI and if I pass the scope
string[] customScopes = new string[] { "api://<MyApiId>/<MyScopeName>" };
I can make calls to my custom API but cannot send emails.
If I try to add both I only get scopes in the AuthenticationResult for whichever one came first in the scopes array.
If I make two calls to AuthenticateAsync, one for each scope, and use the two separate AccessTokens retrieved for their respective calls to my api and to send an email it all works but I am not sure why I should need to manage two different access tokens in my application to one registered application in the azure portal.
I found this Multiple resources in a single authorization request question which mentions not being able to mix scopes from microsoft graph and outlook.office365.com but no indication as to why or if the same applies to mixing customAPI scopes and graph scopes