使用C#控制台程序获取Azure Data Factory信息时遇ExpiredAuthenticationToken异常
解决Azure AD令牌过期问题:刷新机制与最佳实践
首先直接说结论:默认的Azure AD访问令牌过期时间是1小时,微软不支持通过配置延长这个时间——这是出于安全设计的考量,短期令牌能降低泄露后的风险。你的问题核心是没有实现令牌的自动刷新逻辑,下面给你具体的解决方案:
为什么你的代码会出现过期异常?
你当前的代码是一次性获取令牌后就长期使用,但访问令牌1小时后就会失效。而且你用的是ClientCredential(客户端凭证流),这种认证方式本身没有刷新令牌(Refresh Token),所以需要的是在令牌过期前重新获取新的访问令牌。
优化方案:缓存+自动刷新令牌
我们可以通过缓存令牌、定期检查过期时间的方式,确保每次调用Azure API时都使用有效的令牌。修改后的代码如下:
// 缓存令牌结果,避免重复请求 private static AuthenticationResult _cachedAuthResult; // 线程锁保证多线程环境下的安全 private static readonly object _tokenLock = new object(); public static async Task<string> GetValidAccessTokenAsync() { lock (_tokenLock) { // 检查缓存令牌是否有效:存在且距离过期还有至少5分钟缓冲时间 if (_cachedAuthResult != null && _cachedAuthResult.ExpiresOn > DateTime.UtcNow.AddMinutes(5)) { return _cachedAuthResult.AccessToken; } } // 令牌过期或不存在,重新获取 var context = new AuthenticationContext( $"{ConfigurationManager.AppSettings["ActiveDirectoryEndpoint"]}{ConfigurationManager.AppSettings["ActiveDirectoryTenantId"]}"); var credential = new ClientCredential( ConfigurationManager.AppSettings["ApplicationId"], ConfigurationManager.AppSettings["Password"]); var newResult = await context.AcquireTokenAsync( resource: ConfigurationManager.AppSettings["WindowsManagementUri"], clientCredential: credential); if (newResult == null) throw new InvalidOperationException("Failed to acquire valid access token"); lock (_tokenLock) { _cachedAuthResult = newResult; } return newResult.AccessToken; } // 异步获取有效凭证,避免.Result导致的死锁 public static async Task<TokenCloudCredentials> GetValidTokenCredentialsAsync() { var token = await GetValidAccessTokenAsync(); return new TokenCloudCredentials(ConfigurationManager.AppSettings["SubscriptionId"], token); }
使用注意事项
- 全程使用async/await:避免用
.Result同步等待,防止长运行控制台应用出现死锁问题。 - 缓冲时间设置:代码里加了5分钟的缓冲,确保在令牌真正过期前就完成刷新,避免刚好在调用API时过期。
- 客户端凭证流的特性:这种认证方式重新获取令牌是安全且高效的,微软的API不会限制合理的请求频率,不用担心频繁调用的问题。
额外提示
如果你是用较新的Azure SDK,建议迁移到**MSAL(Microsoft Authentication Library)**替代旧的ADAL,MSAL提供了更简洁的令牌缓存和自动刷新机制,长期维护性更好。不过上面的修改已经能解决你当前的问题。
内容的提问来源于stack exchange,提问作者Jai




