我有一个 .NET Framework 4.7.2 控制台应用程序,我正在尝试使用 Azure Key Vault secret 进行配置。
我正在使用 app.config ConfigBuilders 来启用 Key Vault 读取。
<configSections>
<section name="configBuilders" type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false"/>
</configSections>
...
<configBuilders>
<builders>
<add name="AzureKeyVault" vaultName="key-vault-name" vaultUri="https://key-vault-name.vault.azure.net" type="Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Azure, Version=1.0.0.0, Culture=neutral"/>
</builders>
</configBuilders>
...
<connectionStrings configBuilders="AzureKeyVault">
<add name="DBConnectionString" connectionString="CheckAzureKeyVault"/
</connectionStrings>
当本地运行时,这可以在 Visual Studio 中运行。当部署到我们的测试 EC2 实例 (Windows Server 2016)、在有权访问 Key Vault 的服务帐户 [使用 Active Directory 集成身份验证] 下运行时,它也可以工作。
如果我将相同的编译文件部署到生产 EC2(也是 Windows Server 2016)并在同一服务帐户下运行它,我会收到以下错误:
Unhandled Exception: System.TypeInitializationException: The type initializer for 'Example.Program' threw an exception. ---> System.Configuration.ConfigurationErrorsException: The configBuilder 'AzureKeyVault' failed during Initialization.: One or more errors occurred. (C:\Example.Program.exe.Config line 21) ---> System.AggregateException: One or more errors occurred. ---> Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/xxxx. Exception Message: Tried the following 4 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/xxx. Exception Message: Tried to get token using Managed Service Identity. Access token could not be acquired. MSI ResponseCode: NotFound, Response: <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/xxx. Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Visual Studio Token provider file not found at "C:\xxx\tokenprovider.json"
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/xxx. Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. ERROR: Please run 'az login' to setup account.
Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/xxx. Exception Message: Tried to get token using Active Directory Integrated Authentication. Access token could not be acquired. Federated service at https://xxx returned error: See inner exception for detail.Inner Exception : Response status code does not indicate success: 400 (BadRequest).
at Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider.<GetAccessTokenAsyncImpl>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.KeyVault.KeyVaultCredential.<PreAuthenticate>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.KeyVault.KeyVaultCredential.<ProcessHttpRequestAsync>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.Azure.KeyVault.KeyVaultClient.<GetSecretsWithHttpMessagesAsync>d__66.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.<GetSecretsAsync>d__50.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder.<<GetAllKeys>b__17_0>d.MoveNext()
--- End of inner exception stack trace ---
at System.AggregateException.Handle(Func`2 predicate)
at Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder.GetAllKeys()
at Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder.Initialize(String name, NameValueCollection config)
at System.Configuration.ConfigurationBuildersSection.CreateAndInitializeBuilderWithAssert(Type t, ProviderSettings ps)
--- End of inner exception stack trace ---
at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
at System.Configuration.ConfigurationManager.get_AppSettings()
at Example.Program..cctor()
--- End of inner exception stack trace ---
at Example.Program.Main(String[] args)
我很难确定为什么它在我们的开发虚拟机上以相同的方式运行应用程序,但在我们的生产虚拟机上却不起作用。两者都安装了.NET Framework 4.8,两者都可以连接到互联网。
在 Prod VM 上,如果我使用 PowerShell 并首先通过 Azure CLI 登录,我就能够成功运行应用程序。仅当我尝试将其作为 Prod VM 上的服务帐户运行时,才会出现错误。
有什么想法吗?
最佳答案
对于此特定错误,我们能够确定它是从自定义域(错误消息“Federated Service at xxx”中列出的域)到 AWS ELB 的 CNAME 条目。由于某种原因,运行应用程序的服务器不喜欢该 CNAME。当我们添加一个主机文件条目将域直接映射到域 Controller 时,它就起作用了。到目前为止,我们还无法解决 CNAME 无法正常运行的根本原因,但我们可以使用主机文件条目来解决这个问题。这可能是我们环境中的一个特定错误,但也许会对某人有所帮助。
关于VM 上安装的 .NET Framework 控制台应用程序无法访问 Azure Key Vault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58107333/