Я установил Azure Keyvault на мое веб-приложение ASP.Net MVC, следуя примеру примера Microsoft Hello Key Vault.
Azure KeyVault (Active Directory) AuthenticationResult по умолчанию имеет истечение в течение одного часа. Итак, через час вы должны получить новый токен аутентификации. KeyVault работает как ожидается в течение первого часа после получения моего первого токена AuthenticationResult, но после истечения 1 часа он не сможет получить новый токен.
К сожалению, для моей производственной среды мне не удалось реализовать это, поскольку я никогда не тестировал один час разработки.
В любом случае, через два дня, пытаясь выяснить, что не так с моим кодом ключа, я придумал решение, которое устраняет все мои проблемы - удаляет асинхронный код, но он чувствует себя очень взломанным. Я хочу узнать, почему он не работал в первую очередь.
Мой код выглядит следующим образом:
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;
}
Подпись метода GetAccessToken должна быть асинхронной для перехода в новый конструктор KeyVaultClient, поэтому я оставил подпись как async, но я удалил ключевое слово ожидания.
С ключевым словом ожидания (там, где он должен быть, и находится в образце):
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;
}
Программа работает отлично при первом запуске. И в течение часа AcquireTokenAsync возвращает тот же оригинальный токен аутентификации, который велик. Но как только токен истекает, AcquiteTokenAsync должен получить новый токен с новой датой истечения срока действия. И это не так - приложение просто зависает. Ошибка не возвращена, ничего.
Поэтому вызов AcquireToken вместо AcquireTokenAsync решает проблему, но я понятия не имею, почему. Вы также заметите, что я передаю "null" вместо "TokenCache.DefaultShared" в конструктор AuthenticationContext в моем примере кода с помощью async. Это означает, что токек истекает немедленно, а не через час. В противном случае вам нужно подождать один час, чтобы воспроизвести поведение.
Я смог воспроизвести это снова в новом проекте MVC, поэтому я не думаю, что это имеет какое-то отношение к моему конкретному проекту. Любое понимание было бы оценено. Но на данный момент я просто не использую async.