簡體   English   中英

在 Linux docker 容器中運行 Asp.Net Core 3.1 的 Azure App Service 是否支持用戶分配的托管標識?

[英]Does Azure App Service running Asp.Net Core 3.1 in a Linux docker container support User Assigned Managed Identity?

我有一個 Asp.Net Core 3.1 應用程序,它使用以下代碼從 Key Vault 讀取其配置:

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 package 的最新版本 - 1.4.0

該應用程序被部署到一個 Azure App Service 上,它有一個 System Managed Identity(簡稱 MI),它可以從相關的 Key Vault 中讀取秘密。 有用。

事實上,當我從 Key Vault 訪問策略中刪除系統 MI 並重新啟動應用服務時,我得到了這個:

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 和密鑰保管庫名稱)

它為我們提供了確實與系統 MI 匹配的 AppId (6f215b10-33a1-4e5d-b3b7-20e8f3d3b587) 和 ObjectId (3d6af26c-af56-4cef-a832-41c2303a8cbe)。

到目前為止,一切都很好。

現在,我將系統 MI 替換為用戶分配的 MI,它可以訪問同一 KV 中的秘密。 但是,重新啟動應用服務不會產生任何好處。 web 應用無法從 Key Vault 中讀取機密,這會中止容器的啟動。 這是 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,但只有一個系統 MI。

所以,問題是——在這種情況下我們是否可以使用用戶分配的 MI?

問題可能是您沒有告訴AzureServiceTokenProvider用戶分配的 MI 的 ID。

在文檔中,您可以看到連接字符串語法示例: https://learn.microsoft.com/en-us/azure/key-vault/service-to-service-authentication#connection-string-support

對於您的情況,請指定一個連接字符串,例如:

RunAs=App;AppId={用戶指定身份的ClientId}

並將其用作令牌提供者的構造函數參數。 默認情況下,提供程序僅嘗試系統分配的 MI。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM