我在跟踪API访问委派权限如何与azure活动目录一起工作时遇到了一些麻烦。我觉得我可能误解了AAD的工作方式。
这是我的设置
我要做的是,用户登录Web应用程序标志。当它登录时,用户能够获取特定Web App App ID A的令牌。用户应该能够使用该令牌并访问具有App ID B的Api服务。我想通过配置整个API Access - > 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中它将调用try to reauthenticate
context.Result = new ChallengeResult();
将重定向到身份验证页面,然后点击AddOpenIdConnect()方法。但是,openIdConnect配置了Web应用程序clientID / ClientSecret / Resource,并且不会正确存储新令牌。它将尝试再次调用GetAccessTokenAsync(),整个过程将进入无限循环。
在该示例中,如果您要在app.settings中注释掉“Anthentication:resource”,您将遇到与无限循环相同的问题。会发生什么是您最初在没有指定资源的情况下正确验证。然后,当您单击时,尝试获取微软图形的令牌,这是一种新资源,它无法在缓存中找到它,然后尝试反复重新验证。
我还注意到acquireAsyncAuthentication仅返回带有bekentype承载的AuthenticationResult。在这种情况下,您将如何获得刷新令牌?
有什么建议吗? 谢谢, 德里克
感谢@jaanus。您所要做的就是将资源更新为web api的clientid并将其传递给AcquireTokenSilentAsync。您可以从天蓝色门户网站获取的Web api id uri无效。
答案 0 :(得分:2)
好的,所以看来这里有很多问题。我会尝试对你有所了解。
将&#34; Web App&#34;的客户端ID添加到&#34; ApiService&#34; knownClientApplications是个好主意。 它允许同时为两个应用程序同意。这实际上只对多租户场景有用。
现在,您的Web App将在某个时刻获取访问令牌。
如果是,则必须指定resource
参数。
此参数向AAD说明您要调用的API。
对于&#34; ApiService&#34;,您应该使用其客户端ID或应用程序ID URI(这是更常见的)。
根据Web App的类型,访问令牌的获取方式略有不同。 对于&#34;传统&#34;后端应用程序,通常使用授权代码授权流程。 在此流程中,您的后端在用户登录后获取授权代码,然后您的Web App可以交换访问令牌的代码。
对于前端JavaScript应用程序,您将使用您允许的隐式授权流程(顺便说一下,无需在API中启用它)。 这个允许您直接从授权端点(/ oauth2 / authorize)访问令牌,而无需像往常那样与令牌端点通信。 如果您愿意,您可以在登录URL片段后立即获取访问令牌。 如果你要走这条路,ADAL.JS会让你更加轻松。
您收到身份验证错误的原因是因为访问令牌可能适用于Microsoft Graph API。您需要为API请求访问令牌。 访问令牌始终仅对一个API有效。