【问题标题】:"HTTP Error 502.5 - Process Failure" accessing Azure Key Vault in Azure PaaS with ASP.NET Core 2.1 WebAPI“HTTP 错误 502.5 - 进程失败”使用 ASP.NET Core 2.1 WebAPI 在 Azure PaaS 中访问 Azure Key Vault
【发布时间】:2019-05-07 08:54:03
【问题描述】:

我在尝试使用托管服务标识访问 Azure Key Vault 时收到错误消息“HTTP 错误 502.5 - 进程失败”/“操作返回了无效的状态代码‘禁止’”。在 Visual Studio 中调试时,但在发布到 Azure Web 应用程序时,它返回 502.5 错误。

我怀疑它与 Azure Key Vault 的权限有关。因为我可以在 Visual Studio 中本地运行它(它是一个新的 Key Vault) - 我知道我有权限。我不确定 Web 应用程序在 Azure 中运行的用户是什么,并且怀疑 Web 应用程序需要访问密钥保管库,但我希望通过启用“托管服务标识”来处理这个问题。

如何正确配置我的应用程序以使用托管服务标识访问密钥保管库?

重现步骤:

  1. 在 Azure 门户中创建新资源组
  2. 创建一个 Azure Key Vault(我称之为“mytestkeyvault”)。添加两个秘密,secret1,secret2,在其中添加一些东西(我使用这个 Azure CLI 脚本来添加 hello/goodbye)

    az keyvault secret set --vault-name 'mytestkeyvault' --name 'Secret1' --value 'Hello'
    az keyvault secret set --vault-name 'mytestkeyvault' --name 'Secret2' --value 'Goodbye'
    
  3. 在 Azure 中创建 Web 应用程序。 启用托管服务标识

  4. 创建一个新的 ASP.NET Core 2.1 WebAPI(我将其命名为“MyKeyVaultTest.Service”)。
  5. 添加 NuGet 包:

    • AspNetCore.KeyVault
    • Microsoft.Azure.Services.AppAuthentication
  6. 编辑 appsettings.json 文件以添加 Key Vault URL:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        }
      },
      "AllowedHosts": "*",
      "AppSettings": {
        "KeyVaultURL": "https://mytestkeyvault.vault.azure.net/"
      }
    }
    
  7. 在 program.cs 文件中,编辑为如下所示,以连接到 appsettings.json 并连接到 keyvault:

    using Microsoft.AspNetCore;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    
    namespace MyKeyVaultTest.Service
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                CreateWebHostBuilder(args).Build().Run();
            }
    
            public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .ConfigureAppConfiguration((context, config) =>
                    {
                        IConfigurationRoot builtConfig = config.Build();
                        ConfigurationBuilder keyVaultConfigBuilder = new ConfigurationBuilder();
                        keyVaultConfigBuilder.AddAzureKeyVault(builtConfig["AppSettings:KeyVaultURL"]);
                        IConfigurationRoot keyVaultConfig = keyVaultConfigBuilder.Build();
                        config.AddConfiguration(keyVaultConfig);
                    })
                    .UseStartup<Startup>();
        }
    }
    
  8. 在值控制器中,编辑为如下所示:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using System.Collections.Generic;
    
    namespace MyKeyVaultTest.Service.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class ValuesController : ControllerBase
        {
            private readonly IConfiguration _configuration;
    
            public ValuesController(IConfiguration configuration)
            {
                _configuration = configuration;
            }
    
            // GET api/values
            [HttpGet]
            public ActionResult<IEnumerable<string>> Get()
            {
                string secret1 = _configuration["Secret1"];
                string secret2 = _configuration["Secret2"];
    
                return new string[] { secret1, secret2 };
            }        
        }
    }
    
  9. 在 Visual Studio 中运行 - 注意值 api 返回我们所期望的:

    ["Hello","Goodbye"]
    
  10. 将项目发布到 Azure。注意它不起作用并返回:

    HTTP 错误 502.5 - 进程失败

    全栈错误:

    Description: The process was terminated due to an unhandled exception.
    Exception Info: Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Operation returned an invalid status code 'Forbidden'
       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 MyKeyVaultTest.Service.Program.&lt;&gt;c.&lt;CreateWebHostBuilder&gt;b__1_0(WebHostBuilderContext context, IConfigurationBuilder config) in D:\a\1\s\MyKeyVaultTest\MyKeyVaultTest.Service\Program.cs:line 27
       at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException&amp; hostingStartupErrors)
       at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
       at MyKeyVaultTest.Service.Program.Main(String[] args) in D:\a\1\s\MyKeyVaultTest\MyKeyVaultTest.Service\Program.cs:line 17
    

【问题讨论】:

  • 你并不真的需要 AspNetCore.KeyVault 这个代码包。它适用于不同的用例,不是第一方 nuget

标签: c# azure asp.net-core asp.net-core-2.1 azure-keyvault


【解决方案1】:

在 Web 应用中启用托管服务标识会创建一个在 Azure 中使用的标识。您仍然需要向该身份授予对 Key Vault 的必要权限。

在 Web 应用中启用 MSI 后,它将显示为可以在 Key Vault 权限配置中分配权限的用户。

【讨论】:

  • 谢谢。在您发布此消息前一分钟,我就想到了这一点。在启用 MSI 后,我是否需要将该主体添加到密钥保管库中,这一点尚不清楚。当您启用 MSI 时,我认为应该更清楚地知道主体已经创建并且需要分配权限。现在来研究如何在 ARM 模板中执行此操作...
猜你喜欢
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多