【发布时间】:2018-07-29 06:26:18
【问题描述】:
我在了解 API 访问委托权限如何与 Azure Active Directory 配合使用时遇到了一些麻烦。我觉得我可能误解了 AAD 工作原理的一个关键方面。
这是我的设置
- 我有一个 Web 应用程序,我们称之为 WebApp。我创造了 Web 应用程序的 AAD 并使用 AAD 应用程序 ID 注册。让我们 称之为 App ID A
- 我有一个 Web Api,我们称之为 ApiService。我还为它创建了一个 AAD 并使用 AAD App ID 注册。让我们全部使用 App ID B。
- 在 AAD App ID A 中,我更新了点击的 API Access -> 所需权限 -> 添加(App ID B ; Web API)权限
- 我已更新 AAD 应用程序 ID B 中的清单,以同意 knownClientApplications 以包含 Web 应用的客户端 ID
- 我还为两个应用程序启用了 oauth2AllowImplicitFlow 清单。
我正在尝试做的是,用户登录到 Web 应用程序标志。当它登录时,用户能够获取特定 Web App App ID A 的令牌。用户应该能够使用该令牌并使用 App ID B 访问 Api 服务。我想通过配置整个 API 访问-> Web 应用程序中的必需权限,它将授予我与登录用户的委托权限,以与 Api 服务 WebApi 进行通信。
当我检查 JWT 令牌时,我注意到有 Microsoft Graph 的声明,但 ApiService 没有。我不应该看到索赔吗?
当我尝试使用令牌时,它会出现 404 身份验证错误。
任何建议表示赞赏, 谢谢, 德里克
更新
回应@joonasw
实际上,我在开始时查看了您编写的示例。
https://joonasw.net/view/aspnet-core-2-azure-ad-authentication
在示例中,Web 应用程序初始化为:
.AddOpenIdConnect(opts =>
{
Configuration.GetSection("OpenIdConnect").Bind(opts);
opts.Events = new OpenIdConnectEvents
{
OnAuthorizationCodeReceived = ctx =>
{
return Task.CompletedTask;
}
};
});
在 HomeController 中,有代码可以检索图形 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;
}
据我了解,当用户最初登录 Web 应用程序时,它将触发 OnAuthorizationCodeReceived() 方法,它将使用 Web 应用程序的 clientId/clientSecret/resource。令牌存储在密钥资源/客户端 ID 下的分布式令牌缓存中。
在示例中,GetAccessTokenAsync() 用于获取令牌以访问图形 API。
就我而言,我希望更新该方法以检索具有不同 clientId/clientSecret/resoruce 的 WebApi 的令牌。在我的情况下,它会 AcquireTokenSilentAsync 将抛出一个 AdalTokenAcquisitionExceptionFilter 因为所需的令牌未存储在缓存中,并且在 AdalTokenAcquisitionExceptionFilter 中它将调用尝试重新验证
context.Result = new ChallengeResult();
它将重定向到身份验证页面,然后点击 AddOpenIdConnect() 方法。但是,openIdConnect 配置了 Web 应用程序 clientID/ClientSecret/Resource 并且不会正确存储新令牌。它将尝试再次调用 GetAccessTokenAsync() 并且整个过程将进入无限循环。
在示例中,如果您要在 app.settings 中注释掉“Anthentication:resource”,您将遇到与无限循环相同的问题。发生的情况是您最初在没有指定资源的情况下正确地进行了身份验证。然后,当您单击时,您尝试获取 microsoft graph 的令牌,这是一个新资源,它在缓存中找不到它,然后尝试一遍又一遍地重新验证。
我还注意到,acquireAsyncAuthentication 只返回一个带有不记名令牌类型的 AuthenticationResult。在这种情况下,您将如何获得刷新令牌?
有什么建议吗? 谢谢, 德里克
更新(解决方案)
感谢@jaanus。您所要做的就是将资源更新为 web api 的 clientid 并将其传递给 AcquireTokenSilentAsync。您可以从 azure 门户获取的 web api id uri 不起作用。
【问题讨论】:
标签: azure-active-directory asp.net-core-webapi azureportal