从Kubernetes Pod调用Azure Keyvault错误请求

问题描述

在将某些服务从Microsoft Service Fabric转换到Kubernetes时,访问Azure Key Vault时遇到问题。在ASP.NET核心ConfigureServices调用中,我们从Microsoft.Extensions.Configuration.AzurekeyvaultConfigurationExtensions调用AddAzurekeyvault,以注入我们配置的一些敏感部分,如下所示。

public void ConfigureServices(IServiceCollection services)
{

    var config = new ConfigurationBuilder()
        .SetBasePath(AppContext.BaseDirectory)
        .AddJsonFile("appsettings.json",optional: false,reloadOnChange: true)
        .AddAzurekeyvault(
            Environment.GetEnvironmentvariable("keyvAULT_LOCATION"),Environment.GetEnvironmentvariable("keyvAULT_CLIENT_ID"),Environment.GetEnvironmentvariable("keyvAULT_CLIENT_SECRET")
        ).Build();

        //...
}

这在本地运行的docker映像中工作正常,但是一旦部署到Azure Kubernetes服务中,则pod失败,并显示以下内容...

Microsoft.Azure.keyvault.Models.keyvaultErrorException: Operation returned an invalid status code 'BadRequest'
   at Microsoft.Azure.keyvault.keyvaultClient.GetSecretsWithHttpMessagesAsync(String vaultBaseUrl,Nullable`1 maxresults,Dictionary`2 customHeaders,CancellationToken cancellationToken)

查看Microsoft.Extensions.Configuration.AzurekeyvaultConfigurationExtensions的源代码,我可以用最少的代码重现此问题。

public void ConfigureServices(IServiceCollection services)
{
    GetSecrets(
        Environment.GetEnvironmentvariable("keyvAULT_LOCATION"),Environment.GetEnvironmentvariable("keyvAULT_CLIENT_SECRET")
    ).GetAwaiter().GetResult();
}

public async Task GetSecrets(string loc,string clientId,string clientSecret)
{
    keyvaultClient.AuthenticationCallback callback =
        (authority,resource,scope) => GetTokenFromClientSecret(authority,clientId,clientSecret);

    IkeyvaultClient _client = new keyvaultClient(callback);

    //Exception thrown here
    var secrets = await _client.GetSecretsAsync(loc).ConfigureAwait(false);
}

private static async Task<string> GetTokenFromClientSecret(string authority,string resource,string clientSecret)
{
    var authContext = new AuthenticationContext(authority);
    var clientCred = new ClientCredential(clientId,clientSecret);
    var result = await authContext.AcquiretokenAsync(resource,clientCred);
    return result.Accesstoken;
}

我的问题是,与本地docker镜像相反,从AKS的Pod中调用此身份验证有什么不同?

我已经确认Pod可以访问更广泛的Internet,密钥库未进行防火墙保护,并且Insights在密钥库日志中显示了某些身份验证失败。客户端ID和密码是正确的,并且具有正确的权限,因为它在Docker中本地工作。我想念什么?

解决方法

我只是在您的计算机,本地集群和AKS集群上运行了您的代码示例。它在所有地方都有效。请检查您的环境。您可能在寻找错误的位置。您的本地环境中一定有东西。尝试在其他环境中运行它。例如:在家(没有VPN)。