You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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);
}

使用注意事项

  1. 全程使用async/await:避免用.Result同步等待,防止长运行控制台应用出现死锁问题。
  2. 缓冲时间设置:代码里加了5分钟的缓冲,确保在令牌真正过期前就完成刷新,避免刚好在调用API时过期。
  3. 客户端凭证流的特性:这种认证方式重新获取令牌是安全且高效的,微软的API不会限制合理的请求频率,不用担心频繁调用的问题。

额外提示

如果你是用较新的Azure SDK,建议迁移到**MSAL(Microsoft Authentication Library)**替代旧的ADAL,MSAL提供了更简洁的令牌缓存和自动刷新机制,长期维护性更好。不过上面的修改已经能解决你当前的问题。

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

火山引擎 最新活动