通过网络代理使用 Azure KeyVault 配置提供程序会引发 HTTP 407 异常

Using the Azure KeyVault Configuration Provider through a network proxy throws a HTTP 407 exception

我正在更新 .NET 6 Blazor Server 应用程序,它使用 .AddAzureKeyVault() 扩展方法将 Azure KeyVault 配置提供程序从旧的 Microsoft.Extensions.Configuration.AzureKeyVault 添加到推荐的 Azure.Extensions.AspNetCore.Configuration.Secrets使用新 SDK 的包。

我遇到的问题是请求通过网络代理。我当前使用旧 SDK 的工作版本是这样的:

using Microsoft.Extensions.Configuration.AzureKeyVault; // 3.1.22
using Microsoft.Azure.Services.AppAuthentication; // 1.6.2
using Microsoft.Azure.KeyVault; // 3.0.5 (this needs to be  version 3.0.0 or greater)

var builder = WebApplication.CreateBuilder(args);

var webProxy = new WebProxy(new Uri("{proxy_url}")) { 
    Credentials = CredentialCache.DefaultNetworkCredentials 
};

var httpClient = new HttpClient(new HttpClientHandler { 
    Proxy = webProxy, SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls 
});

var authenticationCallback = new KeyVaultClient.AuthenticationCallback(
    new AzureServiceTokenProvider().KeyVaultTokenCallback);

var keyVaultClient = new KeyVaultClient(authenticationCallback, httpClient);

builder.Configuration
    .AddAzureKeyVault("{keyvault_url}", keyVaultClient, new DefaultKeyVaultSecretManager());

var output = builder.Configuration
    .GetSection("ApplicationInsights:InstrumentationKey").Value; // successfully retrieves value

使用新的 SDK,我尝试将代理传递到 HttpClientTransport class,但收到 “对代理的代理隧道请求”{proxy_url} ' 失败,状态代码为“407”。“ 异常:

using Azure.Identity; // 1.5.0
using Azure.Security.KeyVault.Secrets; // 1.2.1

var builder = WebApplication.CreateBuilder(args);

var webProxy = new WebProxy(new Uri("{proxy_url}")) { 
    Credentials = CredentialCache.DefaultNetworkCredentials 
};

var httpClient = new HttpClient(new HttpClientHandler { 
    Proxy = webProxy, SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls 
});

var azureCredentialOpts = new DefaultAzureCredentialOptions { 
    Transport = new HttpClientTransport(httpClient) 
};

var secretClient = new SecretClient(new Uri("{keyvault_url}"), 
    new DefaultAzureCredential(azureCredentialOpts));

builder.Configuration
    .AddAzureKeyVault(secretClient, new AzureKeyVaultConfigurationOptions()); 
// throws request to proxy failed with status code '407'

var output = builder.Configuration
    .GetSection("ApplicationInsights:InstrumentationKey").Value;

我可以在 Microsoft 文档中找到关于如何执行此操作的任何提及,以及我找到的任何使用旧 SDK 的示例。我确实在这里找到了这个相关问题 - ,但建议的解决方案对我没有用。

唯一需要注意的是,当我使用 Microsoft.Extensions.Configuration.AzureKeyVault 包时,旧 SDK 确实遇到了同样的“407”异常,我不得不明确地将 Microsoft.Azure.KeyVault 包升级到一个版本3.0.0 让它工作,所以不确定这是否可能相关(可能新的 SDK 不支持网络代理的身份验证?...)

有人知道如何通过代理使用 Azure.Extensions.AspNetCore.Configuration.Secrets 包吗?

设法解决了我的问题,事实证明我在 DefaultAzureCredentialOptions 中设置了代理,而我本应在 SecretClientOptions 中设置它以便与 SecretClient 一起使用。我发现 Microsoft 的这份迁移指南有助于找出我哪里出错了 - https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/keyvault/Azure.Security.KeyVault.Secrets/MigrationGuide.md

需要注意的一件事是我必须使用 Azure.Security.KeyVault.Secrets 包的测试版 v4.3.0-beta.4 否则你必须明确指定租户 ID,从另一个 post 看来因为低于这个的版本没有自动租户发现功能 - .

我的代码的工作版本是这样的:

using Azure.Extensions.AspNetCore.Configuration.Secrets; // v1.2.1
using Azure.Identity; // v1.5.0
using Azure.Security.KeyVault.Secrets; // v4.3.0-beta.4

var builder = WebApplication.CreateBuilder(args);

var webProxy = new WebProxy(new Uri("{proxy_url}")) { 
    Credentials = CredentialCache.DefaultNetworkCredentials 
};

var httpClient = new HttpClient(new HttpClientHandler { 
    Proxy = kpmgWebProxy, SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls 
});

var secretClientOptions = new SecretClientOptions { 
    Transport = new HttpClientTransport(httpClient) 
}; 

// `Azure.Security.KeyVault.Secrets` package version < 4.3.0 does not have the tenant discovery feature, therefore you will have to set this i nthe options. 
/*var defaultAzureCredentialOptions = new DefaultAzureCredentialOptions()
{
    VisualStudioTenantId = "",
};*/

var secretClient = new SecretClient(
    new Uri(azureKeyVaultUrl), 
    new DefaultAzureCredential(/*defaultAzureCredentialOptions*/), 
    secretClientOptions);

builder.Configuration
    .AddAzureKeyVault(secretClient, new KeyVaultSecretManager());

var output = builder.Configuration
    .GetSection("ApplicationInsights:InstrumentationKey").Value;