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

Azure SQL使用Active Directory Default认证启动缓慢问题求助

问题描述

我们正将EF Core连接Azure SQL的连接字符串从Visual Studio用户名密码认证,切换为Authentication=Active Directory Default认证方式。切换后应用启动时长变为原来的3倍,推测延迟出现在令牌获取环节——原因是DefaultAzureCredential会依次尝试多种认证机制,而大部分机制在当前环境下不可用,导致耗时过长。我们曾尝试通过环境变量禁用Visual Studio以外的认证方式,但没有效果,求可行解决方案。

解决方案:自定义EF Core连接拦截器

为解决该问题,我开发了一个EF Core连接拦截器,手动控制令牌获取逻辑,仅启用Visual Studio认证,并添加令牌缓存避免重复请求。以下是实现细节:

拦截器注册

按照EF Core的拦截器注册流程完成注册即可。

拦截器代码实现

public class AadAuthenticationInterceptor : DbConnectionInterceptor
{
    // 使用AAD认证时强制异步打开连接,避免同步操作阻塞
    public override InterceptionResult ConnectionOpening(
        DbConnection connection,
        ConnectionEventData eventData,
        InterceptionResult result)
        => throw new InvalidOperationException("使用AAD认证时请异步打开数据库连接。");

    public override async ValueTask<InterceptionResult> ConnectionOpeningAsync(
        DbConnection connection,
        ConnectionEventData eventData,
        InterceptionResult result,
        CancellationToken cancellationToken = default)
    {
        var sqlConnection = (SqlConnection)connection;

        var token = await GetCachedAzureToken();
        sqlConnection.AccessToken = token;
        return result;
    }

    // 从缓存获取令牌,缓存过期则重新请求
    public static async Task<string> GetCachedAzureToken()
    {
        AzureTokenItem tokenItem = new AzureTokenItem();
        
        var appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "YourFolder");
        var cacheFilePath = Path.Combine(appDataFolder, "AzureTokenCache.txt");

        if (File.Exists(cacheFilePath))
        {
            var tokenText = File.ReadAllText(cacheFilePath);
            var cachedToken = JsonSerializer.Deserialize<AzureTokenItem>(tokenText);
            if (cachedToken.ExpiresOn > DateTime.Now)
            {
                return cachedToken.Token;
            }
        }

        // 仅保留Visual Studio认证,禁用其他所有认证方式
        var tokenCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
        {
            ExcludeEnvironmentCredential = true,
            ExcludeInteractiveBrowserCredential = true,
            ExcludeAzurePowerShellCredential = true,
            ExcludeSharedTokenCacheCredential = true,
            ExcludeVisualStudioCodeCredential = true,
            ExcludeManagedIdentityCredential = true,
            ExcludeAzureCliCredential = true,
        });

        // 请求Azure SQL的访问令牌
        var azureToken = await tokenCredential.GetTokenAsync(new TokenRequestContext(new[] { "https://database.windows.net/" }));

        tokenItem = new AzureTokenItem
        {
            ExpiresOn = azureToken.ExpiresOn.LocalDateTime,
            Token = azureToken.Token
        };

        // 创建缓存目录并写入令牌
        Directory.CreateDirectory(appDataFolder);
        File.WriteAllText(cacheFilePath, JsonSerializer.Serialize(tokenItem));
        
        return tokenItem.Token;
    }
}

// 令牌缓存实体类
public class AzureTokenItem
{
    public DateTime ExpiresOn { get; set; }
    public string Token { get; set; }
}

方案优势

  • 避免无效认证尝试:通过DefaultAzureCredentialOptions精准禁用所有非Visual Studio的认证机制,彻底消除无效尝试带来的延迟。
  • 令牌缓存复用:将有效令牌缓存到本地文件,在过期前直接复用,减少重复向Azure AD请求令牌的次数。
  • 强制异步操作:拦截同步打开连接的行为,避免同步令牌请求阻塞主线程,优化启动时的响应速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 17:37:39