it-roy-ru.com

KeyVaultErrorException: операция вернула недопустимый код состояния "Запрещено"

Я пытаюсь настроить свое веб-приложение, размещенное в Azure, для чтения настроек из Azure KeyVault.

Я следовал этому руководству: https://anthonychu.ca/post/secrets-aspnet-core-key-vault-msi/

В примере показано, как получить доступ к настройкам приложения из KeyVault с помощью конфигурации:

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();

Я добавил переменную среды KEYVAULT_ENDPOINT в настройки приложения. Я включил MSI в службе приложений и авторизовал своего пользователя Azure и свое приложение из политик доступа к ключевым хранилищам:

 enter image description here

С помощью операций Get и List:

 enter image description here

И я добавил секрет в хранилище ключей. Работая локально, я могу получить доступ к секрету.

Но мой ASP .NET Core сайт не запускается при запуске с этим в журналах 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

Я проверил, что переменные среды MSI_ENDPOINT и MSI_SECRET существуют, вызвав SET из консоли отладки.  enter image description here

Я также вижу переменную KEYVAULT_ENDPOINT.

Любые предложения, что может пойти не так или что попробовать дальше? Поскольку он работает локально, это должно быть проблемой аутентификации, но я полагаю, что аутентификация выполняется локально с моим пользователем Azure, который я авторизовал в хранилище ключей, а не в качестве службы приложений Azure. 

3
zola25

Это хитроумно, но проблема с вашей настройкой заключается в том, что вы включили «Авторизованное приложение» при создании политики доступа для вашего KeyValut.

Вы можете видеть это, потому что у вас есть «Приложение + Приложение» на скриншоте. Я полагаю, вы создали политику, в которой ваше веб-приложение является основным и авторизованным приложением. Это создает цикл.

Чтобы эта настройка работала, просто удалите существующую политику и создайте новую, в которой вы выбираете только принципала:

 enter image description here

11
JleruOHeP

выберите только принципал и добавьте веб-приложение, не выбирайте авторизованное приложение  enter image description here

1
Viral Jain

Чтобы решить эту проблему, мне пришлось добавить IP-адреса веб-приложения в брандмауэр, поскольку не все из них добавляются при выборе «Разрешить доверенные службы Microsoft ...»

 outbound ips of the web app

 Azure Key Vault firewall settings

Спасибо: https://azidentity.azurewebsites.net/post/2019/01/03/key-vault-firewall-access-by-Azure-app-services

1
Mark Szabo

Я встречал подобные проблемы раньше, когда системы разработки и производства не работали одинаково при работе с переменными среды.

Моя первая область, в которой нужно рассмотреть эти сценарии, - проверить, правильно ли вы префиксировали переменные среды с помощью ASPNETCORE_ в вашей производственной системе. Этот префикс является префиксом по умолчанию для веб-узлов ASP.NET Core.

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

** Обратите внимание, что в вашем коде я никогда не вижу, чтобы вы использовали MSI_ENDPOINT или MSI_SECRET. Я вижу только, как вы используете KEYVAULT_ENDPOINT

Если вы хотите явно установить префикс на что-то другое, префикс, который вы хотите использовать, может быть передан в качестве аргумента при инициализации веб-хоста через конфигурацию.

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