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

本地运行时DefaultAzureCredential为何调用ManagedIdentityCredential?

问题根因

DefaultAzureCredential的自动回退逻辑只会处理凭据类型不适用、认证请求返回标准认证错误码(如400、401、404)的场景,不会处理非预期格式的响应错误。你本地运行时返回的403 (GlobalBlock)是本地网络代理、VPN或安全软件拦截托管标识元数据端点(169.254.169.254)返回的HTML错误页,不是Azure认证服务返回的标准JSON错误响应,因此内部异常提示'<' is an invalid start of a value(HTML内容以<开头,不符合JSON格式要求)。这种非预期错误会直接终止认证流程,不会继续尝试后续的VisualStudioCredential。
另外你的代码存在一处笔误:ConfigurationWebHostDefaults应为ConfigureWebHostDefaults,不修正的话应用本身无法正常启动。

解决方案

两种经过验证的方案都可以实现本地调试、Azure部署环境的无缝兼容,不需要发布前改代码:

方案1:基于运行环境动态调整凭据选项

利用.NET的环境判断逻辑,本地开发环境下排除托管标识凭据,Azure生产环境正常启用托管标识,是最简单稳定的方案:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, builder) =>
        {
            var builtConfig = builder.Build();
            Uri keyVaultUrl = new(builtConfig["keyVaultUrl"]);
            DefaultAzureCredentialOptions credentialOptions = new()
            {
                ExcludeEnvironmentCredential = true,
                ExcludeSharedTokenCredential = true
            };

            // 本地开发环境排除托管标识探测,避免拦截导致的异常
            if (context.HostingEnvironment.IsDevelopment())
            {
                credentialOptions.ExcludeManagedIdentityCredential = true;
            }

            builder.AddAzureKeyVault(keyVaultUrl, new DefaultAzureCredential(credentialOptions));
        })
        // 修正原代码笔误
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

使用该方案需要确保:

  • 本地Visual Studio已登录拥有目标Key Vault读取权限的Azure账号
  • Azure应用服务的应用设置中ASPNETCORE_ENVIRONMENT值为Production(Azure默认配置,无需手动修改)

方案2:自定义凭据链显式控制回退逻辑

如果不想依赖环境判断,可以手动组合凭据链,缩短托管标识的请求超时时间,本地环境下MI请求失败后自动回退到本地开发工具凭据:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(builder =>
        {
            var builtConfig = builder.Build();
            Uri keyVaultUrl = new(builtConfig["keyVaultUrl"]);
            
            // 按优先级排列凭据:Azure环境优先用托管标识,本地自动回退到VS/Azure CLI凭据
            TokenCredential combinedCredential = new ChainedTokenCredential(
                new ManagedIdentityCredential(new ManagedIdentityCredentialOptions
                {
                    Retry = { NetworkTimeout = TimeSpan.FromSeconds(2) } // 本地MI探测2秒超时即放弃
                }),
                new VisualStudioCredential(),
                new AzureCliCredential()
            );

            builder.AddAzureKeyVault(keyVaultUrl, combinedCredential);
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
排查注意点
  • 无论用哪种方案,都要确保访问Key Vault的身份(Azure上是应用的系统托管标识,本地是你VS登录的账号)已经被授予Key Vault的Key Vault Secrets User角色,否则会返回权限不足的403错误
  • 如果本地开了全局代理/VPN,建议将Azure托管标识元数据地址169.254.169.254加入代理直连列表,减少不必要的拦截

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:24:18