繁体   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