Поддерживает ли Azure служба приложений Asp. Net Core 3.1 в контейнере Linux docker Назначенная пользователем управляемая идентификация? - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть Asp. Net Core 3.1 приложение, которое считывает свою конфигурацию из хранилища ключей, используя следующий код:

var keyVaultEndpoint = builtConfig["ProductKeyVaultUri"];
if (!string.IsNullOrEmpty(keyVaultEndpoint))
{
    var azureServiceTokenProvider = new AzureServiceTokenProvider();
    var keyVaultClient = new KeyVaultClient(
        new KeyVaultClient.AuthenticationCallback(
            azureServiceTokenProvider.KeyVaultTokenCallback));
    config.AddAzureKeyVault(keyVaultEndpoint, keyVaultClient,
        new DefaultKeyVaultSecretManager());
}

В нем используется самая последняя версия пакета Microsoft.Azure.Services.AppAuthentication на сегодняшний день - 1.4.0

Приложение развернуто в службе приложений Azure с системным идентификатором (для краткости MI), который может считывать секреты из соответствующего хранилища ключей. Оно работает.

Действительно, когда я удаляю System MI из политики доступа к Key Vault и перезапускаю Службу приложений, я получаю следующее:

Unhandled exception. Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Access denied. Caller was not found on any access policy.
Caller: appid=6f215b10-33a1-4e5d-b3b7-20e8f3d3b587;oid=3d6af26c-af56-4cef-a832-41c2303a8cbe;numgroups=0;iss=https://sts.windows.net/2...b/
Vault: a...v;location=eastus2
   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.Extensions.Hosting.HostBuilder.BuildAppConfiguration()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at Gateway.Program.Main(String[] args)
/opt/startup/init_container.sh: line 20:    10 Aborted                 (core dumped) dotnet Gateway.dll

(я удалил tenantId и имя хранилища ключей)

Это дает нам AppId (6f215b10-33a1-4e5d-b3b7-20e8f3d3b587) и ObjectId (3d6af26 c -af56-4cef-a832-41c2303a8cbe), которые действительно соответствуют MI системы.

Пока все хорошо.

Теперь я заменяю MI системы на MI, назначенный пользователем, который имеет доступ к секретам в том же KV. Тем не менее, перезапуск службы приложений не приносит никакой пользы. Веб-приложение не может прочитать секреты из хранилища ключей, которое прерывает запуск контейнера. Вот что docker журналы говорят мне:

Unhandled exception. Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/2...b. Exception Message: Tried the following 3 methods to get an access token, but none of them worked.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/2...b. Exception Message: Tried to get token using Managed Service Identity. Access token could not be acquired. Received a non-retryable error. MSI ResponseCode: BadRequest, Response: {"statusCode":400,"message":"Unable to load requested managed identity.","correlationId":"1b0ee635-0805-4438-8ae8-747e9f6dd7c2"}
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/2...b. Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Environment variable LOCALAPPDATA not set.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/2...b. Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. /bin/bash: az: No such file or directory


   at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.GetAuthResultAsyncImpl(String resource, String authority, CancellationToken cancellationToken)
   at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.<get_KeyVaultTokenCallback>b__8_0(String authority, String resource, String scope)
   at Microsoft.Azure.KeyVault.KeyVaultCredential.PostAuthenticate(HttpResponseMessage response)
   at Microsoft.Azure.KeyVault.KeyVaultCredential.ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   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.Extensions.Hosting.HostBuilder.BuildAppConfiguration()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at Gateway.Program.Main(String[] args)
/opt/startup/init_container.sh: line 20:    10 Aborted                 (core dumped) dotnet Gateway.dll

Из чего я заключаю, что docker должно быть явно указано имя назначенного пользователем MI. Это имеет смысл, потому что у Службы приложений может быть много MI, назначенных пользователем, но только один System MI.

Итак, вопрос в том, можем ли мы вообще использовать MI, назначенные пользователем, в этом сценарии?

1 Ответ

0 голосов
/ 12 февраля 2020

Возможно, проблема в том, что вы не говорите AzureServiceTokenProvider идентификатор назначенного пользователем MI.

Здесь, в документации, вы можете увидеть примеры синтаксиса строки подключения: https://docs.microsoft.com/en-us/azure/key-vault/service-to-service-authentication#connection -string-support .

Для вашего случая укажите строку подключения, например:

RunAs = App; AppId = {ClientId назначенного пользователем идентификатора}

И использовать это в качестве аргумента конструктора для поставщика токенов. По умолчанию провайдер пытается использовать только назначенный системой MI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...