Azure active directory AAD API访问委托权限如何工作?
我在了解API访问代理权限如何与azure active directory一起工作时遇到了一些问题。我觉得我可能误解了AAD工作原理的一个关键方面 这是我的设置Azure active directory AAD API访问委托权限如何工作?,azure-active-directory,asp.net-core-webapi,azureportal,Azure Active Directory,Asp.net Core Webapi,Azureportal,我在了解API访问代理权限如何与azure active directory一起工作时遇到了一些问题。我觉得我可能误解了AAD工作原理的一个关键方面 这是我的设置 我有一个Web应用程序,我们称之为WebApp。我创造了 Web应用程序的AAD,并使用AAD应用程序ID注册。让我们 称之为应用程序ID A 我有一个Web Api,我们称之为ApiService。我还为它创建了一个AAD,并注册了一个AAD应用程序ID。让我们看看所有的it应用程序ID B 在AAD应用程序ID A中,我已更新了单
.AddOpenIdConnect(opts =>
{
Configuration.GetSection("OpenIdConnect").Bind(opts);
opts.Events = new OpenIdConnectEvents
{
OnAuthorizationCodeReceived = ctx =>
{
return Task.CompletedTask;
}
};
});
在HomeController中,有用于检索graph api的令牌的代码
private async Task<string> GetAccessTokenAsync()
{
string authority = _authOptions.Authority;
string userId = User.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");
var cache = new AdalDistributedTokenCache(_cache, _dataProtectionProvider, userId);
var authContext = new AuthenticationContext(authority, cache);
//App's credentials may be needed if access tokens need to be refreshed with a refresh token
string clientId = _authOptions.ClientId;
string clientSecret = _authOptions.ClientSecret;
var credential = new ClientCredential(clientId, clientSecret);
var result = await authContext.AcquireTokenSilentAsync(
"https://graph.microsoft.com",
credential,
new UserIdentifier(userId, UserIdentifierType.UniqueId));
return result.AccessToken;
}
它将重定向到身份验证页面,然后点击AddOpenIdConnect()方法。但是,openIdConnect配置了web应用clientID/ClientSecret/Resource,因此无法正确存储新令牌。它将再次尝试调用GetAccessTokenAsync(),整个过程将进入无限循环
在本例中,如果您要注释掉app.settings中的“antentication:resource”,您将在无限循环中遇到同样的问题。发生的情况是,您最初在没有指定资源的情况下正确地进行了身份验证。然后,当您单击尝试获取新资源microsoft graph的令牌时,它在缓存中找不到该令牌,然后尝试一次又一次地重新验证
我还注意到acquireAsyncAuthentication只返回带有承载令牌类型的AuthenticationResult。在这种情况下,如何获取刷新令牌
有什么建议吗?
谢谢
德里克
更新(解决方案)
多亏了@jaanus。您所要做的就是将资源更新为web api的clientid,并将其传递到AcquireTokenSilentAsync。您可以从azure门户获取的web api id uri无效 好吧,看来这里有很多问题。我会尽量让你明白这件事 将“Web App”的客户端id添加到“ApiService”knownClientApplications是一个好主意。 它允许同时对两个应用程序进行许可。不过,这实际上只适用于多租户场景 现在,您的Web应用程序将在某个时候获取访问令牌。 当它这样做时,它必须指定一个
资源
参数。
此参数告诉AAD您希望调用哪个API。
对于“ApiService”,您应该使用它的客户机id或应用程序id URI(这更常见)
根据Web应用程序的类型,访问令牌的获取方式略有不同。
对于“传统”后端应用程序,通常使用授权码授权流。
在这个流程中,在用户登录后,您的后端将获得一个授权代码,然后您的Web应用程序可以将该代码交换为访问令牌
对于前端JavaScript应用程序,您将使用隐式授权流,这是您允许的(顺便说一下,不需要在API中启用它)。
这允许您直接从授权端点(/oauth2/authorize)获取访问令牌,而无需像通常那样与令牌端点通信。 如果您愿意,您可以在登录URL片段后立即获得访问令牌。 如果您选择这条路线,那么ADAL.JS会使这一点变得更加容易 出现身份验证错误的原因是,访问令牌可能是针对Microsoft Graph API的。您需要为API请求访问令牌。
访问令牌始终仅对一个API有效。感谢您的回复。我已经用更多的细节更新了我的帖子。问题是,当我指定资源时,我会得到一个无限循环,这可能是我设置的结果。我的设置基于您提供的示例,该示例非常有用,但我认为我缺少一个方面,即在处理两个不同的应用程序ID时,如何配置openId以及如何将其存储在分布式缓存中。”这一方面允许您直接从授权端点(/oauth2/authorize)获取访问令牌不必像通常那样与令牌端点交谈。“难道你不必将Web API AAD端点标记为本机与Web API来实现这一点吗?因此,在OnAuthorizationCodeReceived中,你必须做的是将代码交换为令牌。您可以对两种不同的资源使用它两次。然后,ADAL将使用其令牌缓存缓存令牌。在我的示例中,它由分布式缓存支持。然后,您可以使用AcquireTokenSilent从缓存中获取令牌。由于AAD在您交换代码时也会提供刷新令牌,因此如果需要,ADAL将自动刷新令牌。隐式流用于单页应用程序,可以通过man在任一类型上启用
context.Result = new ChallengeResult();