0

I'm updating a .NET 6 Blazor Server app that uses the .AddAzureKeyVault() extension method to add an Azure KeyVault configuration provider from the old Microsoft.Extensions.Configuration.AzureKeyVault over to the recommended Azure.Extensions.AspNetCore.Configuration.Secrets package that uses the new SDK.

The complication I have is that the request goes through a network proxy. The current working version I have that uses the old SDK is this:

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

With the new SDK I attempted to pass the proxy into the HttpClientTransport class but recieve a "The proxy tunnel request to proxy '{proxy_url}' failed with status code '407'." exception:

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;

I could find any mention of how to do this in the Microsoft docs and any examples I find use the old SDK. I did find this related question here - Azure .NET v4 SDK Proxy Configuration in .NET Framework, but the proposed solution never worked for me.

Only other thing to note was I did get this same '407' exception with the old SDK when using the Microsoft.Extensions.Configuration.AzureKeyVault package and I had to explicitly upgrade the Microsoft.Azure.KeyVault package to a version over 3.0.0 to get it to work, so not sure if this may be related (potentially the new SDK doesn't support the auth with the network proxy?...)

Would anyone know how I could use the Azure.Extensions.AspNetCore.Configuration.Secrets package through a proxy?

QTheIntro
  • 55
  • 10
  • [Reference](https://www.exai.com/blog/407-proxy-authentication-required#:~:text=Summary-,The%20407%20Proxy%20Authentication%20Required%20error%20code%20indicates%20that%20the,between%20the%20client%20and%20server.) . – RithwikBojja Feb 11 '22 at 09:45

1 Answers1

3

Managed to resolve my issue, turns out I was setting the proxy in DefaultAzureCredentialOptions when I should have been setting it in SecretClientOptions to be used with the SecretClient. I found this migration guide from Microsoft helpful in finding out where I was going wrong - https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/keyvault/Azure.Security.KeyVault.Secrets/MigrationGuide.md

One thing to note is I had to use the beta version v4.3.0-beta.4 of the Azure.Security.KeyVault.Secrets package otherwise you have to specify the tenant id explicitly, from another post it seems to be because versions below this don't have the automatic tenancy discovery feature - Visual Studio 2019 TokenService.exe has failed with unexpected error: TS003: Error, TS004: Unable to get access token.

The working version of my code is this:

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;
QTheIntro
  • 55
  • 10