You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ADAL的ASP.NET MVC5 Web App调用自定义Azure AD API方案问询

解决Azure AD + ADAL 3.x场景下获取含用户标识的API访问令牌问题

首先得明确你遇到的核心问题:授权码是一次性的,没法重复兑换不同资源的令牌;而用客户端凭据模式(AcquireTokenAsync(app_id, app_secret))拿到的令牌是服务到服务的,完全没有用户上下文,所以你的API自然识别不了调用者。下面给你两种可行的解决思路,以及各自的优劣:

就地解决方案:利用刷新令牌静默获取目标API的令牌

这是不需要重构现有代码的最优解,因为你已经通过授权码兑换到了Graph的令牌,ADAL其实已经帮你缓存了用户的刷新令牌——这个令牌可以用来兑换同一用户、不同资源的访问令牌。

具体操作步骤:

  • 先确认你的MVC应用的Azure AD注册里,已经添加了对自有WebAPI的委托权限,并且完成了管理员同意(如果是租户内应用,可能不需要,但跨租户场景必须)。
  • 确保ADAL的TokenCache和用户会话绑定:Web应用默认的内存缓存是全局的,会导致用户串号,所以要把缓存序列化后存在用户的Session(或分布式缓存)里,比如在认证完成后执行:
    // 在Katana中间件的认证回调逻辑中
    var authContext = new AuthenticationContext(authority);
    // 兑换Graph令牌后,将缓存序列化存入Session
    Session["TokenCache"] = authContext.TokenCache.Serialize();
    
  • 当需要调用自有API时,取出用户的缓存,用AcquireTokenSilentAsync静默获取API的令牌:
    var authority = "https://login.microsoftonline.com/你的租户ID";
    var apiResourceId = "你的WebAPI的Azure AD资源ID";
    var mvcClientId = "你的MVC应用客户端ID";
    var mvcClientSecret = "你的MVC应用客户端密钥";
    
    // 获取当前登录用户的唯一标识
    var userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
    // 从Session取出用户的令牌缓存
    var tokenCache = new TokenCache();
    tokenCache.Deserialize((byte[])Session["TokenCache"]);
    
    var authContext = new AuthenticationContext(authority, tokenCache);
    // 静默获取目标API的令牌,这个令牌会包含用户的UPN、用户ID等声明
    var result = await authContext.AcquireTokenSilentAsync(apiResourceId, mvcClientId, new UserIdentifier(userId, UserIdentifierType.UniqueId));
    
    // 用result.AccessToken调用你的WebAPI即可
    
    这个方法的核心是复用用户已有的刷新令牌,不需要用户再次登录,就能拿到带用户上下文的API令牌。

备选方案:迁移Graph调用到WebAPI,兑换API资源的授权码

如果你的业务架构更倾向于API作为中间层,所有外部服务调用都通过API完成,可以考虑这个方案:

  • 修改MVC应用的认证流程,请求的资源ID改为自有WebAPI的资源ID,这样授权码兑换的是API的令牌(自带用户标识)。
  • MVC应用调用WebAPI时带上这个令牌,API验证通过后,再通过On-Behalf-Of(OBO)流程,用用户的令牌兑换Graph的令牌,去调用Graph接口。
  • 这个流程需要在WebAPI的Azure AD注册里添加Graph的委托权限,并且配置允许OBO流程(在Azure门户的应用注册中完成权限配置和管理员同意)。

方案对比:哪个更适合你?

  • 如果你的MVC应用本身需要直接调用Graph(比如前端要展示用户的个人信息),就地解决方案绝对是首选,不需要重构现有代码,只需要添加几行获取令牌的逻辑,成本极低,而且完全兼容现有业务。
  • 如果你的业务逻辑更偏向于分层架构,希望所有外部服务调用都通过WebAPI统一处理,迁移方案更优——这样MVC应用只需要持有WebAPI的权限,不需要直接访问Graph,安全性更高,也便于后续的权限管理和维护。

最后补充一句:虽然ADAL 3.x现在还能用,但微软已经停止更新了,后续如果有机会,还是建议迁移到MSAL,它对Azure AD的新特性支持更好,令牌缓存的管理也更省心。

内容的提问来源于stack exchange,提问作者evilSnobu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:24:39