我有一个单页应用,使用adal-angular.js / adal.js [client]对Azure中的用户进行身份验证。
返回的令牌将插入到auth标头中并传递给Web API [server]。此Web API使用代表工作流程(https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof)为应用生成新的访问令牌
然后,此令牌用于调用下游API [API1]。
因此,下游API会重复此过程以获取新令牌以调用另一个API [API2]。在这一点上,我得到了上述错误。
从[client]传递到[server]的令牌中的aud值是[server] app的应用程序ID。 从[服务器]传递到[API1]的令牌中的aud值是[API1]应用程序的应用程序URI。 到目前为止一切都很好。
当我在[API1]应用程序中调用AcquireTokenAsync时,出现以下错误:
AADSTS70002:验证凭据时出错。 AADSTS50013:断言受众群体声明与所需值不符。断言中的观众是' http:// application_uri .com /'而预期的受众群体是' snip -a1d5-e82e84f4e19e'或此应用程序的一个应用程序Uris与App ID' snip -a1d5-e82e84f4e19e'
[API1]的相关代码:
public static async Task<string> GetApplicationTokenOnBehalfOfUser(string appId, string appKey)
{
var clientCredential = new ClientCredential(appId, appKey);
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as
System.IdentityModel.Tokens.BootstrapContext;
var userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
var userAccessToken = bootstrapContext.Token;
var userAssertion = new UserAssertion(userAccessToken, _assertionType, userName);
var authority = string.Format(System.Globalization.CultureInfo.InvariantCulture, _aadInstance, _tenant);
var userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
var authContext = new AuthenticationContext(authority, new TokenCache());
var result = await authContext.AcquireTokenAsync(_resourceId, clientCredential, userAssertion);
var accessToken = result.AccessToken;
return accessToken;
}
其中: appId =&#34; snip -a1d5-e82e84f4e19e&#34;
&#34; aud&#34; BootstrapContext.Token的值是: &#34; aud&#34;:&#34; http:// application_uri .com /&#34;
如果我更改以上内容以使用&#34; aud&#34;来自令牌的值作为ClientCredential中的appId,我得到了这个错误:
AADSTS65001:用户或管理员未同意使用ID为&#39; http:// application_uri .com /&#39;的应用程序。发送此用户和资源的交互式授权请求。
我这样做了吗? 感谢。
答案 0 :(得分:0)
AADSTS70002:验证凭据时出错。 AADSTS50013:断言受众群体声明与所需值不符。断言中的观众是'http://application_uri.com/',预期的观众是'snip-a1d5-e82e84f4e19e'或者此应用程序的应用程序Uris之一,App ID为'snip-a1d5-e82e84f4e19e'
要使用代表流,我们需要为 API1 提供访问令牌,并提供 clientId 和保密 API1请求 API2 的访问令牌。
AADSTS65001:用户或管理员未同意使用ID为“http://application_uri.com/”的应用。发送此用户和资源的交互式授权请求。
在该租户用户可以使用该应用之前,相应的服务主体必须首先通过权限授予注册到该租户。 API2 是否不在用户登录的租户中?
如果我理解正确,我们需要在您的SPA的 client_id 中指定API1清单中的knownClientApplications
(http://application_uri.com/'),并且还需要将API1的权限设置为SPA。之后,当用户登录您的SPA时,API1应用程序也会注册到用户的租户。
有关多层应用程序的更多详细信息,请参阅以下文档:
How to sign in any Azure Active Directory (AD) user using the multi-tenant application pattern
答案 1 :(得分:0)
为了实现这一点,我必须为AP2的API1添加以下委派权限。 Azure Permissions