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 и свое приложение из политик доступа к хранилищу ключей:

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

С помощью операций получения и списка:

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

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

Но мой сайт 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 из консоли отладки. KeyVaultErrorException: операция вернула недопустимый код состояния «Запрещено»

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

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

Здесь это не по теме, но помните, что KeyVaultClient является IDisposable, поэтому было бы лучше заключить его с помощью "using"

Andrzej Martyna 10.08.2018 10:26
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
31
1
48 704
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

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

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

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

** Note that in your code I don't ever see you using MSI_ENDPOINT or MSI_SECRET. I only see you using KEYVAULT_ENDPOINT

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

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

Спасибо, для чего нужен префикс ASPNETCORE_? MSI_ENDPOINT и MSI_SECRET читаются самим пакетом Microsoft.Azure.KeyVault для аутентификации MSI (я думаю).

zola25 02.07.2018 20:32

@ zola25 Я не был уверен в этих двух ключах, поскольку они не были определены в вашем вопросе. Однако префикс ASPNETCORE_ является префиксом по умолчанию для веб-узлов ASP.NET Core, если вы явно не измените его.

Svek 03.07.2018 05:32
Ответ принят как подходящий

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

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

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

Это правильный ответ, все работает нормально.

Ashish-BeJovial 04.05.2021 12:59

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

Чтобы решить эту проблему, мне пришлось добавить 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

Убедитесь, что субъект-служба, который вы используете, добавлен и имеет соответствующие разрешения для операций, которые вы хотите выполнить (ключи / секреты и т. д.):

Проверьте, есть ли у KeyVault ограниченный доступ к сети, переключите, чтобы проверить, является ли это проблемой или нет:

В AZ KV политики доступа ... при выборе только основного должны работать.

Другая возможность заключается в том, что субъекту службы требуются разрешения API для Key Vault. На портале Azure перейдите к субъекту-службе, затем выберите разрешения API в меню слева. Затем щелкните Добавить разрешения. Здесь вы можете выбрать Key Vault и сохранить. Это позволит коду получить секреты хранилища ключей.

Я хочу добавить сюда еще один случай с теми же симптомами / сообщениями об ошибках. Azure keyvault вернул значение "Запрещено", когда один из секретов был отключен.

У меня были все необходимые разрешения - я получал доступ к хранилищу ключей с помощью Get и List, предоставленных для секретов (я использовал только секреты) для управляемой идентификации моей службы приложений.

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

Если вы добавили политику доступа во время входа в Azure через Visual Studio, вам придется выйти и снова войти в систему, чтобы обновить свои разрешения.

Другие вопросы по теме