簡體   English   中英

如何從 Azure Functions (v2) 使用 Azure Key Vault

[英]How to use Azure Key Vault from Azure Functions (v2)

我正在嘗試使用 Azure Functions (v2) 中的 Azure Key Vault;
當我在本地運行時,它可以工作,但是當我將此代碼發布到 Azure 時:

try
{
    var vault_url = "https://mykeyvault.vault.azure.net/";
    var azureServiceTokenProvider = new AzureServiceTokenProvider();
    var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback), client);

    fbAppSecret = (await kvClient.GetSecretAsync(vault_url, "facebook-appid-secret-...")).Value;
}
catch (Exception ex)
{
    error = ex.ToString();
}

它給出了一個包含此內容的異常(請檢查您是否在具有 MSI 設置的 Azure 資源上運行。):

Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connectionstring: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/66ad737e-d8cc-4ab3-abf0-feab50685d13. Exception Message: Tried the following 3 methods to get an access token, but none of them worked.
Parameters: Connectionstring: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/66ad737e-d8cc-4ab3-abf0-feab50685d13. Exception Message: Tried to get token using Managed Service Identity. Unable to connect to the Managed Service Identity (MSI) endpoint. Please check that you are running on an Azure resource that has MSI setup.
Parameters: Connectionstring: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/66ad737e-d8cc-4ab3-abf0-feab50685d13. Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Visual Studio Token provider file not found at "D:\local\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json"
Parameters: Connectionstring: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/66ad737e-d8cc-4ab3-abf0-feab50685d13. Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. 'az' is not recognized as an internal or external command,
operable program or batch file.


   at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.<GetAccessTokenAsyncImpl>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Azure.KeyVault.KeyVaultCredential.<PostAuthenticate>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Azure.KeyVault.KeyVaultCredential.<ProcessHttpRequestAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Azure.KeyVault.KeyVaultClient.<GetSecretWithHttpMessagesAsync>d__65.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.<GetSecretAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at ApelosUrgentesFunctionApp.MyFunctions.<Run>d__1.MoveNext() in C:\Users\tonyv\source\repos\siteApelosUrgentes\ApelosUrgentesFunctionApp\MyFunctions.cs:line 50

然后我發現 MSI 意味着托管服務標識,可以在 Azure Functions 門戶上啟用:

托管服務身份

但是啟用它后,還有另一個異常:

Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Access denied
   at Microsoft.Azure.KeyVault.KeyVaultClient.<GetSecretWithHttpMessagesAsync>d__65.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.<GetSecretAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at ApelosUrgentesFunctionApp.MyFunctions.<Run>d__1.MoveNext() in C:\Users\tonyv\source\repos\siteApelosUrgentes\ApelosUrgentesFunctionApp\MyFunctions.cs:line 50

我將 Azure Functions App 添加為 Reader,然后添加為 Owner,但仍然得到

我將 Azure Functions 應用程序添加為所有者,但仍然得到

Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Access denied
at Microsoft.Azure.KeyVault.KeyVaultClient.<GetSecretWithHttpMessagesAsync>d__65.MoveNext()

綜合管理

我還添加了所有訪問策略,但仍然拒絕訪問

美聯社 AP2

檢查 Kudu,AppSettings:

https://myfunctionapp.scm.azurewebsites.net/api/settings

{"deployment_branch":"master","SCM_TRACE_LEVEL":"1","SCM_COMMAND_IDLE_TIMEOUT":"60","SCM_LOGSTREAM_TIMEOUT":"1800","SCM_BUILD_ARGS":"","aspnet:PortableCompilationOutput":"true","aspnet:PortableCompilationOutputSnapshotType":"Microsoft.Web.Compilation.Snapshots.SnapshotHelper, Microsoft.Web.Compilation.Snapshots, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35","aspnet:DisableFcnDaclRead":"true","SCM_GIT_USERNAME":"windowsazure","SCM_GIT_EMAIL":"windowsazure","webpages:Version":"3.0.0.0","webpages:Enabled":"true","webactivator:assembliesToScan":"Kudu.Services.Web","MSDEPLOY_RENAME_LOCKED_FILES":"1","FUNCTIONS_EXTENSION_VERSION":"beta","ScmType":"None","WEBSITE_AUTH_ENABLED":"False","REMOTEDEBUGGINGVERSION":"15.0.26730.8","WEBSITE_DISABLE_MSI":"false","AzureWebJobsDashboard":"DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xQ","WEBSITE_CONTENTAZUREFILECONNECTIONSTRING":"DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xq","WEBSITE_CONTENTSHARE":"apelosurgentesfunctionapp","WEBSITE_SLOT_NAME":"Production","AzureWebJobsStorage":"DefaultEndpointsProtocol=https;AccountName=functionapp;AccountKey=xq","WEBSITE_SITE_NAME":"FunctionApp"}

如何解決這個問題?

我在您的圖片中發現的一個細節是在訪問策略中,您的服務主體下有“應用程序 + 應用程序”。

您是否能夠刪除服務主體並僅使用服務主體中的應用程序將其添加回來,而將授權應用程序留空

如本文所示:

https://docs.microsoft.com/en-us/azure/key-vault/key-vault-secure-your-key-vault#authentication-using-azure-active-directory

當您使用授權應用程序時,必須代表登錄用戶訪問的應用程序,因此代表自身工作的應用程序無法按預期工作。

為什么它在本地主機上開箱即用,但在已發布的版本中我必須遵循所有這些步驟?

您可以參考Azure 服務身份驗證擴展以獲取有關它如何在 localhost 上工作的更多信息。 它使用您的登錄帳戶,您的帳戶可以訪問 Azure Key Vault 資源。

在此處輸入圖片說明

如果發布到Azure 函數,可以使用Azure MSI 函數,它會自動注冊Azure AD 應用程序。然后我們還需要分配訪問KeyVault 的權限。

我也在我這邊進行了測試,它工作正常。 請確保在您的情況下正確啟用了 MSI。 您可以使用 Azure kudu 工具檢查MSI_SECRETMSI_ENDPOINT

請使用 AzureServiceTokenProvider 的PrincipalUsed屬性來檢查正在使用什么AppId進行身份驗證,或者換句話說,正在使用的托管服務標識是什么。 您收到“拒絕訪問”這一事實意味着可以獲取訪問令牌,但 MSI 無權訪問 Key Vault。 您確實授予了對服務主體的訪問權限,但很可能不是授予正確的服務主體。 使用PrincipalUsed 中返回的AppId使用 Key Vault“訪問策略”搜索“服務主體”。

這是 Azure Functions 當前最簡單的方法https://docs.microsoft.com/en-gb/azure/app-service/app-service-key-vault-references

例如特定版本@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)

例如獲取最新版本(注意:尾部斜杠!) @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)

暫無
暫無

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

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