0

I am trying to use DefaultAzureCredential to connect to a key vault hosted in Azure using the code below:

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;    // Azure.Extensions.AspNetCore.Configuration.Secrets 1.2.2
using Azure.Identity;                        // Azure.Identity 1.6.0

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

            builder.AddAzureKeyVault(keyVaultUrl, new DefaultAzureCredential(options));
        })
        .ConfigurationWebHostDefaults(webBuilder => 
        {
            webBuilder.UseStartup<Startup>();
        });

The code works fine when my web application is published to Azure, and successfully uses the system managed identity I have set up, but when running locally I experience the following exception:

Azure.Identity.AuthenticationFailedException: 'ManagedIdentityCredential authentication failed. Managed Identity response was not in the expected format. See the inner exception for details.

Status: 403 (GlobalBlock)

and the inner exception reveals:

'<' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.

I understand that managed identities are not expected to work locally but I thought that the point of using DefaultAzureCredential was to fall back to another credential type instead, as per Microsoft's documentation. Therefore, I was expecting it to use VisualStudioCredential instead; in fact, if I explicitly use VisualStudioCredential then the application does run locally (but not when published to Azure, of course).

I'm at a bit of a loss to explain the behaviour I am seeing and am not sure how to configure DefaultAzureCredential so that it works both locally and in Azure. Does anybody have any ideas?

I am using Visual Studio 2019 and .NET 5.0.

Chris Young
  • 79
  • 2
  • 9
  • Does this answer your question? [How to use DefaultAzureCredential in both local and hosted Environment (Azure and On-Premise) to access Azure Key Vault?](https://stackoverflow.com/questions/70616431/how-to-use-defaultazurecredential-in-both-local-and-hosted-environment-azure-an) – Ecstasy Jun 16 '22 at 07:47
  • [When using DefaultAzureCredential, web app tries to use ManagedIdentityCredential on local computer](https://stackoverflow.com/questions/67529379/when-using-defaultazurecredential-web-app-tries-to-use-managedidentitycredentia) – Ecstasy Jun 16 '22 at 07:48
  • That's quite odd. I would expect it to be unable to connect to the default MI endpoint that is used in Azure VMs. In App Service there is an env var that tells it the address, but in VMs there is not. It is a specific IP address that hosts the Instance Metadata Service (IMDS). Maybe in your environment that is somehow returning something? – juunas Jun 16 '22 at 08:14
  • @DeepDave-MT, thanks for your suggestions. The first seems to suggest using EnvironmentCredential but I don't seem to have permissions to register an app in Azure so I don't have a client ID or client secret to set. The second link I actually found previously but it doesn't seem to have a solution. – Chris Young Jun 16 '22 at 09:45

2 Answers2

0

Do you have the Azure Arc agent installed on your local machine by any chance?

This will create a Managed Server Identity and DefaultAzureCredential will try to use that.

The agent would be installed in Program Files\AzureConnectedMachineAgent and set these environment variables:

IMDS_ENDPOINT=http://localhost:40342
IDENTITY_ENDPOINT=http://localhost:40342/metadata/identity/oauth2/token

https://learn.microsoft.com/en-us/azure/azure-arc/servers/managed-identity-authentication

Adriaan
  • 17,741
  • 7
  • 42
  • 75
davesc
  • 1
  • 2
-1

I encountered the same issue and got it sorted.

private static IConfigurationBuilder ConnectToKeyVault(IConfigurationBuilder configurationBuilder,
                                                                    string keyVaultNameSpace,
                                                                    string keyVaultSettingsEnvironment)
        {

            try
            {


                var option = new DefaultAzureCredentialOptions
                {
                    ExcludeAzureCliCredential = true,
                    ExcludeEnvironmentCredential = true,
                    ExcludeInteractiveBrowserCredential = true,
                    ExcludeVisualStudioCodeCredential = true,
                    ExcludeManagedIdentityCredential = true,
                };

                var secretClient = new SecretClient(new Uri($"https://{keyVaultNameSpace}-{keyVaultSettingsEnvironment}.vault.azure.net/"),
                                                        new DefaultAzureCredential(option) 
                                                        );
                configurationBuilder.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());

            }
            catch (Exception ex)
            {
                throw new KeyVaultException($"{ExceptionMessgae.KeyVaultExceptionMessage} : {keyVaultNameSpace}-{keyVaultSettingsEnvironment}", ex.InnerException);
            }

            return configurationBuilder;
        }

Fix was to keep DefaultAzureCredentialOptions enable for desired.

The following credential types if enabled will be tried, in order - EnvironmentCredential, ManagedIdentityCredential, SharedTokenCacheCredential, InteractiveBrowserCredential

Ref: How to use DefaultAzureCredential in both local and hosted Environment (Azure and On-Premise) to access Azure Key Vault?

monika
  • 9
  • 3