Tempo limite do AcquireTokenAsync do Active Directory do KeyVault do Azure quando chamado de forma assíncrona

Eu configurei o Azure Keyvault no meu aplicativo Web ASP.Net MVC, seguindo o exemplo no MicrosoftHello Key Vault aplicativo de amostra.

O KeyVault do Azure (Active Directory) AuthenticationResult, por padrão, tem uma hora de validade. Portanto, após uma hora, você deve obter um novo token de autenticação. O KeyVault está funcionando conforme o esperado na primeira hora após a obtenção do meu primeiro token AuthenticationResult, mas após a expiração de 1 hora, ele falha ao obter um novo token.

Infelizmente, tive uma falha no meu ambiente de produção para que eu percebesse isso, pois nunca testei a última hora em desenvolvimento.

De qualquer forma, depois de mais de dois dias tentando descobrir o que havia de errado com o código do meu keyvault, encontrei uma solução que corrige todos os meus problemas - remova o código assíncrono -, mas parece muito hacky. Quero descobrir por que não estava funcionando em primeiro lugar.

Meu código fica assim:

public AzureEncryptionProvider() //class constructor
{
   _keyVaultClient = new KeyVaultClient(GetAccessToken);
   _keyBundle = _keyVaultClient
     .GetKeyAsync(_keyVaultUrl, _keyVaultEncryptionKeyName)
     .GetAwaiter().GetResult();
}

private static readonly string _keyVaultAuthClientId = 
    ConfigurationManager.AppSettings["KeyVaultAuthClientId"];

private static readonly string _keyVaultAuthClientSecret =
    ConfigurationManager.AppSettings["KeyVaultAuthClientSecret"];

private static readonly string _keyVaultEncryptionKeyName =
    ConfigurationManager.AppSettings["KeyVaultEncryptionKeyName"];

private static readonly string _keyVaultUrl = 
    ConfigurationManager.AppSettings["KeyVaultUrl"];

private readonly KeyBundle _keyBundle;
private readonly KeyVaultClient _keyVaultClient;

private static async Task<string> GetAccessToken(
    string authority, string resource, string scope)
{
   var clientCredential = new ClientCredential(
       _keyVaultAuthClientId, 
       _keyVaultAuthClientSecret);
   var context = new AuthenticationContext(
       authority, 
       TokenCache.DefaultShared);
   var result = context.AcquireToken(resource, clientCredential);
   return result.AccessToken;
}

A assinatura do método GetAccessToken deve ser assíncrona para passar para o novo construtor KeyVaultClient; portanto, deixei a assinatura como assíncrona, mas removi a palavra-chave wait.

Com a palavra-chave wait lá, (do jeito que deveria ser e está na amostra):

private static async Task<string> GetAccessToken(string authority, string resource, string scope)
{
   var clientCredential = new ClientCredential(_keyVaultAuthClientId, _keyVaultAuthClientSecret);
   var context = new AuthenticationContext(authority, null);
   var result = await context.AcquireTokenAsync(resource, clientCredential);
   return result.AccessToken;
}

O programa funciona bem na primeira vez em que o executo. E por uma hora, o AcquireTokenAsync retorna o mesmo token de autenticação original, o que é ótimo. Porém, quando o token expirar, o AcquiteTokenAsync deverá obter um novo token com uma nova data de validade. E não - o aplicativo simplesmente trava. Nenhum erro retornado, nada.

Assim, chamar AcquireToken em vez de AcquireTokenAsync resolve o problema, mas não faço ideia do porquê. Você também notará que estou passando 'null' em vez de 'TokenCache.DefaultShared' para o construtor AuthenticationContext no meu código de exemplo com async. Isso é forçar o toke a expirar imediatamente em vez de após uma hora. Caso contrário, você terá que esperar uma hora para reproduzir o comportamento.

Consegui reproduzir isso novamente em um novo projeto MVC, então não acho que tenha algo a ver com o meu projeto específico. Qualquer insight seria apreciado. Mas, por enquanto, apenas não estou usando assíncrono.

questionAnswers(2)

yourAnswerToTheQuestion