我有一个应用程序,该应用程序需要访问自定义API以及通过Graphs API发送电子邮件的功能。当我获得访问令牌时,我似乎只能传递图形或我的api范围,而不能同时传递两者。
我如下创建我的应用程序
_clientApp = PublicClientApplicationBuilder.Create(ClientId)
.WithAuthority(AzureCloudInstance.AzurePublic, Tenant)
.Build();
然后我进行如下认证
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);
}
如果我通过了范围
string[] graphsScopes = new string[] { "user.read" };
我可以成功发送电子邮件,但是我无法通过我的customAPI进行调用,如果我通过了范围,则可以通过此方法进行>
string[] customScopes = new string[] { "api://<MyApiId>/<MyScopeName>" };
我可以调用自定义API,但不能发送电子邮件。
如果我尝试同时添加两者,则我只会在AuthenticationResult中获得范围,无论是范围数组中最先出现的范围。
如果我对AuthenticateAsync进行两次调用,每个作用域一次,并使用针对他们对api的各自调用而检索到的两个单独的AccessToken,并发送电子邮件,那么这一切都可以,但是我不确定为什么我需要管理两个不同的访问令牌访问我的应用程序中的令牌到azure门户中一个已注册的应用程序。
[我发现了这个Multiple resources in a single authorization request问题,其中提到无法混合Microsoft graph和Outlook.office365.com的范围,但没有说明为什么或是否同样适用于混合customAPI范围和图形范围的问题
我有一个应用程序,该应用程序需要访问自定义API以及通过Graphs API发送电子邮件的功能。当我获得访问令牌时,我似乎只能传递图形或我的api范围,但是...
至少在静默获取令牌时,您需要两次调用AcquireToken。这是因为访问令牌仅对一个API有效,由令牌中的听众(aud)声明命名。因此,要调用两个API,您需要两个不同的访问令牌。