Azure AD AcquireTokenOnBehalfOf调用报错:无效受众问题排查
问题分析与解决方案
核心问题:令牌受众不匹配
你遇到的InvalidAuthenticationToken(无效受众)错误,本质是用来调用Microsoft Graph的令牌,其受众(aud声明)不是Graph API,而是你的API应用注册(client_id 2对应的api://xxx资源)。
具体原因拆解
- Angular端令牌的受众限制:你的Angular代码同时请求了两个不同资源的scope——
api://xxx/access_as_user(属于你的API应用)和Mail.ReadWrite(属于Microsoft Graph)。MSAL在这种场景下,返回的令牌受众是第一个scope对应的资源(即你的API应用),这个令牌只能用来访问你的API,不能直接调用Graph API。 - AcquireTokenOnBehalfOf的使用误区:你的.NET API代码直接复用了原令牌的scopes请求新令牌,但这里应该明确指定Microsoft Graph专属的scopes,而非混合原API的权限。另外,原令牌作为
UserAssertion是合规的(受众是你的API应用,符合On-Behalf-Of流程要求),但请求目标错误。
分步解决方案
1. 修正.NET API的AcquireTokenOnBehalfOf代码
将请求的scopes改为Microsoft Graph的具体权限,不要复用原令牌的scopes:
_settings = settings; IConfidentialClientApplication app = ConfidentialClientApplicationBuilder .Create(_settings.ClientId) // 此处为你的API应用注册client_id 2 .WithClientSecret(_settings.ClientSecret) .WithTenantId(_settings.TenantId) .Build(); UserAssertion userAssertion = new UserAssertion(microsoftGraphToken.AccessToken); // 明确指定Graph的scopes,格式为完整资源路径+权限 var graphScopes = new[] { "https://graph.microsoft.com/Mail.ReadWrite" }; AuthenticationResult result = await app.AcquireTokenOnBehalfOf(graphScopes, userAssertion) .ExecuteAsync();
2. 使用正确的令牌调用Graph API
必须用On-Behalf-Of流程返回的新令牌创建GraphServiceClient,而非Angular端传来的原令牌:
// 使用AcquireTokenOnBehalfOf返回的result.AccessToken _userClient = new GraphServiceClient( new DelegateAuthenticationProvider( requestMessage => { requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(result.TokenType, result.AccessToken); return Task.CompletedTask; } ) );
3. 检查应用注册配置
确保你的API应用注册(client_id 2)已完成以下配置:
- 添加Microsoft Graph的委派权限
Mail.ReadWrite,并完成管理员同意(针对租户内用户场景) - 在「公开API」中配置了正确的
access_as_user范围,且Angular应用注册(client_id 1)已授权该范围
4. 可选:优化Angular端令牌请求
建议拆分请求逻辑,避免混合不同资源的scope:
- 先请求仅包含
api://xxx/access_as_user的令牌,用于访问你的API - 后续由API通过On-Behalf-Of流程单独获取Graph的令牌
验证步骤
- 用JWT解码工具查看Angular返回的令牌,确认
aud字段为你的API应用的api://xxx - 查看On-Behalf-Of流程返回的新令牌,确认
aud字段为https://graph.microsoft.com - 用新令牌调用Graph的
/me/messages接口,验证是否正常返回数据
内容的提问来源于stack exchange,提问作者Liam Kenny
相关产品推荐
相关产品推荐

