web-dev-qa-db-fra.com

KeyVaultErrorException: l'opération a renvoyé un code d'état non valide "Interdit".

J'essaie de configurer mon application Web, hébergée dans Azure, pour lire les paramètres d'Azure KeyVault.

Je suis ce guide: https://anthonychu.ca/post/secrets-aspnet-core-key-vault-msi/

L'exemple montre comment accéder aux paramètres de l'application à partir de KeyVault avec la configuration:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
     .ConfigureAppConfiguration((ctx, builder) =>
     {
         var keyVaultEndpoint = Environment.GetEnvironmentVariable("KEYVAULT_ENDPOINT");
         if (!string.IsNullOrEmpty(keyVaultEndpoint))
         {
             var azureServiceTokenProvider = new AzureServiceTokenProvider();
             var keyVaultClient = new KeyVaultClient(
                 new KeyVaultClient.AuthenticationCallback(
                     azureServiceTokenProvider.KeyVaultTokenCallback));
             builder.AddAzureKeyVault(
                 keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
         }
     })
    .UseApplicationInsights()
    .UseStartup<Startup>()
    .Build();

J'ai ajouté la variable d'environnement KEYVAULT_ENDPOINT aux paramètres de l'application. J'ai activé MSI sur le service de l'application et j'ai autorisé mon utilisateur Azure et mon application à partir des stratégies d'accès au coffre-fort:

 enter image description here

Avec les opérations Get et List:

 enter image description here

Et j'ai ajouté le secret au coffre à clés. En cours d'exécution localement, je peux accéder au secret.

Mais mon ASP .NET Core site échoue au démarrage avec ceci dans les journaux stdout:

Unhandled Exception: Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Operation returned an invalid status code 'Forbidden'
   at Microsoft.Azure.KeyVault.KeyVaultClient.GetSecretsWithHttpMessagesAsync(String vaultBaseUrl, Nullable`1 maxresults, Dictionary`2 customHeaders, CancellationToken cancellationToken)
   at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.GetSecretsAsync(IKeyVaultClient operations, String vaultBaseUrl, Nullable`1 maxresults, CancellationToken cancellationToken)
   at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.LoadAsync()
   at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.Load()
   at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at Blog.Program.BuildWebHost(String[] args) in D:\a\1\s\[csproj name]\Program.cs:line 22
   at [csproj name].Program.Main(String[] args) in D:\a\1\s\[csproj name]\Program.cs:line 16

J'ai vérifié l'existence des variables d'environnement MSI_ENDPOINT et MSI_SECRET en appelant SET à partir de la console de débogage.  enter image description here

Je peux aussi voir la variable KEYVAULT_ENDPOINT.

Des suggestions sur ce qui pourrait mal se passer ou sur quoi essayer ensuite? Dans la mesure où cela fonctionne localement, il doit s'agir d'un problème d'authentification, mais je crois qu'il authentifie localement avec mon utilisateur Azure que j'ai autorisé dans le coffre de clés, plutôt que sous Azure App Service. 

3
zola25

C'est douteux, mais le problème avec votre configuration est que vous avez activé "Application autorisée" lorsque vous avez créé la stratégie d'accès pour votre KeyValut.

Vous pouvez le voir parce que vous avez "Application + Application" sur votre capture d'écran. J'imagine que vous avez créé la stratégie avec votre application Web en tant qu'application principale et application autorisée. Cela crée un peu une boucle.

Pour que cette configuration fonctionne, supprimez simplement votre stratégie existante et créez-en une nouvelle, en sélectionnant uniquement le principal:

 enter image description here

11
JleruOHeP

sélectionnez uniquement le principal et ajoutez une application Web, ne sélectionnez pas l'application autorisée  enter image description here

1
Viral Jain

Pour résoudre le problème, je devais ajouter les adresses IP de l'application Web au pare-feu, car toutes ne sont pas ajoutées lorsque vous sélectionnez "Autoriser les services Microsoft de confiance ...".

 outbound ips of the web app

 Azure Key Vault firewall settings

Merci à: https://azidentity.azurewebsites.net/post/2019/01/03/key-vault-firewall-access-by-Azure-app-services

1
Mark Szabo

J'ai déjà vu des problèmes comme celui-ci auparavant, les systèmes de développement et de production ne se comportant pas de la même manière face aux variables d'environnement.

Mon premier domaine à examiner dans ces scénarios consiste à vérifier si vous avez correctement préfixé vos variables d'environnement avec ASPNETCORE_ dans votre système de production. Ce préfixe est le préfixe par défaut des hôtes Web ASP.NET Core.

| Key                                |  Value                     |
|====================================|============================|
| ASPNETCORE_KEYVAULT_ENDPOINT       |  xxxxxxxxxxxxxxxx          |
| ASPNETCORE_MSI_ENDPOINT**          |  xxxxxxxxxxxxxxxx          |
| ASPNETCORE_MSI_SECRET**            |  xxxxxxxxxxxxxxxx          |

** Notez que dans votre code, je ne vous vois jamais utiliser MSI_ENDPOINT ou MSI_SECRET. Je ne vois que vous utilisez KEYVAULT_ENDPOINT

Si vous souhaitez définir explicitement le préfixe sur quelque chose d'autre, le préfixe que vous souhaitez utiliser peut être transmis en tant qu'argument lors de l'initialisation de l'hôte Web via la configuration.

.AddEnvironmentVariables("ASPNETCORE_"); // choose your own prefix here
0
Svek