VM 上的 Azure Key Vault 访问引发 OAuth 异常:必须提供 ClientId 选项

Azure Key Vault Access on VM throws OAuth Exception: The ClientId option must be provided

我正在尝试将 Azure Key Vault 访问权限添加到 Azure VM 上的 .Net Core 应用程序 运行。我觉得这应该是一个简单的场景,但是当应用程序启动时我 运行 遇到了麻烦。似乎有些地方配置不正确,或者我使用了错误的依赖项。

VM 在 Azure 中 运行,具有系统分配的托管标识,并且它具有对密钥保管库的 get/list 访问权限。该应用程序是一个 .Net core 3 MVC 应用程序,我正在尝试从密钥库加载配置。

应用程序启动时,应用程序 Window 日志中会显示一系列三个错误。它们看起来都像:

System.ArgumentException:必须提供'ClientId'选项。 (参数'ClientId')<br> 在 Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions.Validate()<br> 在 Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions.Validate(字符串方案)<br> 在 Microsoft.AspNetCore.Authentication.AuthenticationBuilder.<>c__DisplayClass4_0'2.<AddSchemeHelper>b__1(TOptions o)

我在代码中尝试了一些不同的东西,但我仍然遇到同样的错误。这在 Program.cs 文件中,为简洁起见,我删除了环境检查。

      public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((context, config) =>
            {
                    var builtConfig = config.Build();
                    var azureServiceTokenProvider = new AzureServiceTokenProvider();
                    var keyVaultClient = new KeyVaultClient(
                        new KeyVaultClient.AuthenticationCallback(
                            azureServiceTokenProvider.KeyVaultTokenCallback));

                    config.AddAzureKeyVault(
                        $"https://{builtConfig[keyVaultEnvironmentConfigName]}.vault.azure.net/",
                        keyVaultClient,
                        new DefaultKeyVaultSecretManager());
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

有什么想法吗?谢谢!

可能有两处出错了。

  1. 一个在您的 appsetting.json 或 appsetting.production.json 中(如果您重写)应该具有如下所述的正确值 { "keyVaultEnvironmentConfigName": "your Key Vault Name" } 注意:如果您在本地 运行,除非您在 AD 中为本地主机 url 注册,否则它将无法工作。因为在 Azure 门户中,您已为 WebAPP url 配置,所以 运行 在本地将不适用于相同的 clientid。
  2. 如果上面的配置项名称和值正确,则托管标识配置不正确。

注意:如上所述,如果您在本地环境中 运行,请确保在 Azure AD 中添加本地主机 url 或在 DevMode 中绕过 KeyVault。

服务主体是否有权访问 Azure Key Vault?创建服务主体时,您还需要创建可以从 Azure AD 应用程序创建的客户端机密。此客户端密码用于身份验证目的。

我明白我的问题是什么了。密钥保管库访问实际上有效,但无法在 Startup.cs 文件中访问配置。我在 Startup.cs 文件中设置了多个 OAuth 提供程序,第一个配置的是设置 ClientId。这就是我遇到特定错误的原因。

我附上了我的启动函数以及我需要为一切正常工作所做的更改。我注意到我必须在 Program.cs 文件和 Startup.cs 文件中都有 Azure Key Vault 配置,否则不同的东西在应用程序的不同点上不起作用。

原始Startup.Startup函数。也许这里有一个问题导致无法访问 Key Vault 值?

public Startup(IWebHostEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile("devsecrets.json", optional: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
     }

固定Startup.Startup函数:

public Startup(IWebHostEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile("devsecrets.json", optional: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();

        // logic to set useKeyVault has been omitted
        if (useKeyVault)
        {
            var azureServiceTokenProvider = new AzureServiceTokenProvider();
            var keyVaultClient = new KeyVaultClient(
                new KeyVaultClient.AuthenticationCallback(
                    azureServiceTokenProvider.KeyVaultTokenCallback));

            builder.AddAzureKeyVault(
                $"https://{Configuration[keyVaultEnvironmentConfigName]}.vault.azure.net/",
                keyVaultClient,
                new DefaultKeyVaultSecretManager());

            Configuration = builder.Build();
        }
    }