【Azure Entra ID】AcquireTokenForClient 触发 Entra ID 请求风暴?Shared Cache 才是 Web App 登录的正确方式

【Azure Entra ID】AcquireTokenForClient 触发 Entra ID 请求风暴?Shared Cache 才是 Web App 登录的正确方式

问题描述

Web App 调用 Azure Entra ID 中国区认证端点 login.chinacloudapi.cn 获取访问令牌时,产生了异常巨大的 Entra ID 请求量,最终导致请求失败和整体登录不稳定。

问题发生在使用 MSAL 的 AcquireTokenForClient 获取 Token 场景中,表面现象是“Web App 调用 Entra ID 失败”,实质原因则与令牌缓存未生效密切相关。

 

问题解答

Web App 使用的是 Client Credentials Flow(客户端凭据模式),核心实现依赖 MSAL 的 ConfidentialClientApplicationAcquireTokenForClient 方法。
 
优化后的关键代码如下(原文代码):
    var app = ConfidentialClientApplicationBuilder.Create(clientId).WithClientSecret(clientSecret).WithAuthority(new Uri(authority))
        .WithLegacyCacheCompatibility(false).WithCacheOptions(CacheOptions.EnableSharedCacheOptions).Build();

以及在获取访问令牌时:

await app.AcquireTokenForClient(scopes).ExecuteAsync();

围绕上述代码,AcquireTokenForClient 获取 Token 的完整流程可以拆解为以下几个关键点:

 一:ConfidentialClientApplication 是 Token 缓存的承载者

ConfidentialClientApplication 表示 Web App 自身在 Azure Entra ID中的“应用身份”,它不仅负责向 Entra ID发起认证请求,同时内部维护了 MSAL 的访问令牌缓存。如果该对象被频繁创建或生命周期过短,缓存将无法复用,直接导致每次获取 token 都访问 Entra ID。

 

二:WithCacheOptions(CacheOptions.EnableSharedCacheOptions) 的核心作用

.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)

这行代码的意义在于:

  • 显式启用 Shared Token Cache
  • 允许同一应用实例在多个 token 请求之间共享并复用已获取的 access token
  • 在 token 有效期内,MSAL 会优先从缓存返回 token,而不是访问 Entra ID

缺少该配置,或未正确复用 app 对象时,即使使用了 MSAL,也相当于每次 AcquireTokenForClient 都是一次全新的登录请求。

 

三:AcquireTokenForClient 的真实执行逻辑

当调用以下代码时:

await app.AcquireTokenForClient(scopes).ExecuteAsync();

MSAL 实际执行顺序为:

1:在本地缓存中查找匹配 scopes 的 access token
2:如果 token 存在且未过期 → 直接返回(不调用 AAD (Entra ID))
3:如果不存在或已过期 → 才向 login.chinacloudapi.cn 发起一次新的 token 请求
4:将新 token 写入缓存,供后续请求复用

 

  • 应用级别(如 Startup / Singleton)创建一次 ConfidentialClientApplication
  • 启用 .WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
  • 所有业务代码统一调用 AcquireTokenForClient 获取 token

 通过该方式,可以显著降低对 Azure Entra ID的请求压力,避免登录风暴,并提升 Web App 的稳定性。

 

参考资料 

MSAL Token Cache 说明 :https://learn.microsoft.com/en-us/entra/identity-platform/msal-acquire-cache-tokens#acquiring-tokens