使用ManagedIdentity访问Azure Key Vault时出现404认证失败错误
在AWS Workspace上使用Visual Studio 2022(版本17.4.5)运行ASP.NET Core 3.1项目,通过托管标识(ManagedIdentity)访问Azure Key Vault,使用的Azure.Identity版本为1.4.0。
Program.cs代码如下:
public static class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((context, config) => { var objBuiltConfig = config.Build(); var userAssignedClientId = objBuiltConfig[AppKeys.UserAssignedClientId]; var objSecretClient = new SecretClient(new Uri(objBuiltConfig[AppKeys.KeyVaultURL]), new DefaultAzureCredential(new DefaultAzureCredentialOptions{ManagedIdentityClientId = userAssignedClientId})); config.AddAzureKeyVault(objSecretClient, new KeyVaultSecretManager()); }).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }
以管理员模式打开Visual Studio 2022完成账号身份认证后,运行应用触发以下错误:
Azure.Identity.AuthenticationFailedException HResult=0x80131500 Message=ManagedIdentityCredential authentication failed: Service request failed. Status: 404 (Not Found) Content: <?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> Headers: Date: Thu, 16 Feb 2023 09:20:47 GMT Connection: close Server: EC2ws Content-Length: 337 Content-Type: text/html Source=Azure.Identity StackTrace: at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex) at Azure.Identity.ManagedIdentityCredential.<GetTokenImplAsync>d__9.MoveNext() at System.Threading.Tasks.ValueTask`1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at Azure.Identity.ManagedIdentityCredential.<GetTokenAsync>d__7.MoveNext() at Azure.Identity.DefaultAzureCredential.<GetTokenFromSourcesAsync>d__14.MoveNext() at System.Threading.Tasks.ValueTask`1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at Azure.Identity.DefaultAzureCredential.<GetTokenImplAsync>d__12.MoveNext() at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex) at Azure.Identity.DefaultAzureCredential.<GetTokenImplAsync>d__12.MoveNext() at System.Threading.Tasks.ValueTask`1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at Azure.Identity.DefaultAzureCredential.<GetTokenAsync>d__11.MoveNext() at System.Threading.Tasks.ValueTask`1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at Azure.Core.Pipeline.BearerTokenAuthenticationPolicy.AccessTokenCache.<GetHeaderValueFromCredentialAsync>d__9.MoveNext() at Azure.Core.Pipeline.BearerTokenAuthenticationPolicy.AccessTokenCache.<GetHeaderValueAsync>d__6.MoveNext() at Azure.Core.Pipeline.BearerTokenAuthenticationPolicy.AccessTokenCache.<GetHeaderValueAsync>d__6.MoveNext() at System.Threading.Tasks.ValueTask`1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at Azure.Core.Pipeline.BearerTokenAuthenticationPolicy.<AuthenticateAndAuthorizeRequestAsync>d__12.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter.GetResult() at Azure.Security.KeyVault.ChallengeBasedAuthenticationPolicy.<AuthorizeRequestOnChallengeAsyncInternal>d__9.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at Azure.Core.Pipeline.BearerTokenAuthenticationPolicy.<ProcessAsync>d__11.MoveNext() at Azure.Core.Pipeline.RedirectPolicy.<ProcessAsync>d__5.MoveNext() at Azure.Core.Pipeline.RetryPolicy.<ProcessAsync>d__11.MoveNext() at Azure.Core.Pipeline.RetryPolicy.<ProcessAsync>d__11.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter.GetResult() at Azure.Core.Pipeline.HttpPipeline.<SendRequestAsync>d__18.MoveNext() at System.Threading.Tasks.ValueTask`1.get_Result() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult() at Azure.Security.KeyVault.KeyVaultPipeline.<SendRequestAsync>d__29.MoveNext() at Azure.Security.KeyVault.KeyVaultPipeline.<GetPageAsync>d__17`1.MoveNext() at Azure.Core.PageResponseEnumerator.FuncAsyncPageable`1.<AsPages>d__2.MoveNext() at Azure.Core.PageResponseEnumerator.FuncAsyncPageable`1.<AsPages>d__2.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult(Int16 token) at Azure.AsyncPageable`1.<GetAsyncEnumerator>d__6.MoveNext() at Azure.AsyncPageable`1.<GetAsyncEnumerator>d__6.MoveNext() at Azure.AsyncPageable`1.<GetAsyncEnumerator>d__6.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult(Int16 token) at Azure.Extensions.AspNetCore.Configuration.Secrets.AzureKeyVaultConfigurationProvider.<LoadAsync>d__10.MoveNext() at Azure.Extensions.AspNetCore.Configuration.Secrets.AzureKeyVaultConfigurationProvider.<LoadAsync>d__10.MoveNext() at Azure.Extensions.AspNetCore.Configuration.Secrets.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 TestProject.Program.Main(String[] args) in D:\Users\User101\TestProject\Program.cs:line 16 This exception was originally thrown at this call stack: [External Code]
核心原因
AWS Workspace本质是EC2实例,没有Azure托管标识服务,直接通过ManagedIdentityCredential请求会返回404。当前代码强制指定用户分配的托管标识ClientId,导致DefaultAzureCredential仅尝试托管标识认证路径,忽略了Visual Studio已登录的身份。
修复步骤
- 修改认证配置:移除
ManagedIdentityClientId的指定,让DefaultAzureCredential自动尝试所有可用认证方式(包括Visual Studio已登录账户)。修改后的代码:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((context, config) => { var objBuiltConfig = config.Build(); // 不指定ManagedIdentityClientId,允许DefaultAzureCredential自动选择认证源 var objSecretClient = new SecretClient(new Uri(objBuiltConfig[AppKeys.KeyVaultURL]), new DefaultAzureCredential()); config.AddAzureKeyVault(objSecretClient, new KeyVaultSecretManager()); }).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
验证账号权限:确认Visual Studio中登录的Azure账号,对目标Key Vault拥有
Key Vault Secrets User或更高权限(如Key Vault Contributor)。可选:强制禁用托管标识认证:设置环境变量
AZURE_IDENTITY_DISABLE_MANAGED_IDENTITY_CREDENTIAL=true,直接跳过托管标识认证路径,强制使用Visual Studio登录身份。
额外说明
DefaultAzureCredential的默认认证优先级为:环境变量 → 托管标识 → Visual Studio → Visual Studio Code → Azure CLI → Azure PowerShell。在非Azure环境(如AWS Workspace)中,托管标识路径不可用,需让它自动 fallback 到其他可用认证源。
内容的提问来源于stack exchange,提问作者santosh kumar patro

