如何在.NET Core中使用MSAL.net获取Azure AD用户令牌
适用认证流程
你的场景(已登录用户访问自研Web API,Web API需要携带用户身份调用下游API)对应OAuth 2.0标准中的代理流(On-Behalf-Of Flow,简称OBO流),这是MSAL.NET针对服务端代表已登录用户访问下游资源指定的标准流程,不要误用客户端凭据流(该流仅能获取应用身份令牌,不携带用户上下文)。
核心调用方法
你需要调用IConfidentialClientApplication实例的AcquireTokenOnBehalfOf方法获取有效用户令牌。
具体实现步骤
- 第一步:在.NET Core后端初始化MSAL机密客户端。传入你在AAD应用注册中拿到的客户端ID、租户ID,以及配置的客户端凭据(客户端密钥或证书均可),参考代码:
// 建议在依赖注入容器中注册为单例 IConfidentialClientApplication confidentialClient = ConfidentialClientApplicationBuilder .Create(builder.Configuration["AzureAd:ClientId"]) .WithTenantId(builder.Configuration["AzureAd:TenantId"]) // 若使用证书认证,替换为.WithCertificate(yourCert)即可 .WithClientSecret(builder.Configuration["AzureAd:ClientSecret"]) .Build();
- 第二步:从当前API的请求上下文中,提取调用方传入的访问你自身API的不记名令牌(即用户登录后获取、用来访问你开发的Web API的JWT令牌),将其封装为
UserAssertion对象。 - 第三步:构造下游API对应的权限范围(scope),传入scope和
UserAssertion实例调用AcquireTokenOnBehalfOf方法,执行后即可拿到用于访问下游API的有效用户令牌,参考代码:
// 从当前HttpContext提取传入的访问令牌 string incomingAccessToken = await HttpContext.GetTokenAsync("Bearer", "access_token"); UserAssertion userAssertion = new UserAssertion(incomingAccessToken); // 下游API权限范围,固定格式为「下游API的应用ID URI/.default」 string[] downstreamScopes = new[] { "api://下游API的客户端ID/.default" }; AuthenticationResult authResult = await confidentialClient .AcquireTokenOnBehalfOf(downstreamScopes, userAssertion) .ExecuteAsync(); // authResult.AccessToken 即为可直接用于下游API调用的有效用户令牌 string downstreamAccessToken = authResult.AccessToken;
关键注意事项
- 提前在AAD应用注册页面,给你的Web API配置对应下游API的委托权限,且完成管理员/用户同意流程,否则调用时会抛出权限不足异常。
- MSAL内置令牌缓存机制,无需手动实现令牌存储、过期刷新逻辑,相同用户、相同权限范围的令牌在有效期内会自动从缓存读取,减少不必要的AAD请求。
- 不要在该场景下使用
AcquireTokenForClient方法,该方法属于客户端凭据流,返回的令牌仅代表应用本身身份,不携带已登录用户的上下文信息。
内容的提问来源于stack exchange,提问作者Maulik Dave
相关产品推荐
相关产品推荐

