При доступе к секретному доступу Azure Key Vault периодически не удается установить соединение с исключением сокетов - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть веб-приложение MVC 5, работающее в .NET 4.7.2 и размещенное в Azure AppService, которое использует хранилище ключей Azure для хранения секретов.В проекте используется пакет Microsoft.Azure.KeyVault 3.0.3 NuGet, а секреты доступны с помощью KeyVaultClient и .GetSecretAsync().Все ресурсы расположены в одном и том же регионе Azure.

В большинстве случаев это работает очень хорошо, и примерно в 90% случаев он возвращает секрет в миллисекундах.

Working Key Vault Access

Но время от времени вызов для доступа к хранилищу ключей не выполняется.Это не проявляется как исключение, выбрасываемое SDK, но веб-приложение зависает.В конце концов - и обычно примерно через 1 минуту, но иногда дольше - секрет возвращается, и все снова в порядке.Это связано с тем, что в SDK используется шаблон повторных попыток, который будет пытаться получить секрет.

Рассматривая Application Insights для AppService, я вижу, что запрос GET, сгенерированный SDK, получает ответ HTTP 500 отВыдается ключ Vault и SocketException с кодом результата ConnectFailure.

Exception

Исключение составляет:

Exception

Глядя на телеметрию и пошагово просматривая код, нет никакого элемента общности или очевидной причины.Кажется, это совершенно случайно.

Суть в том, что AppService, размещенный на Azure , иногда не может подключиться к хранилищу ключей, размещенному на Azure, в одном и том же центре обработки данных, используя последнюю платформу и версию SDK.

Кто-нибудь еще видел это или есть идеи?Я искал вокруг и нашел несколько случаев, когда люди сталкивались с той же проблемой, но ни у кого нет причины или решения.

РЕДАКТИРОВАТЬ (1): Я уже пытался раскрутить новое хранилище ключей в другом регионе.полностью, и проблема остается точно такой же.

1 Ответ

0 голосов
/ 05 февраля 2019

Мы столкнулись с тем же поведением в нашем проекте, где KeyVault большую часть времени работал бы быстро и надежно, а затем периодически переставал отвечать или время от времени возвращался без видимой причины, чтобы объяснить причину.Это происходило на всех уровнях нашего приложения, от API до функций Azure и инструментов командной строки.

В конце концов нам пришлось обойти это, кэшируя секреты в памяти, чтобы избежать слишком частого попадания в KeyVault, гденаш класс AppSettings будет кэшировать их внутри.В дополнение к этому мы также настроили наш DI-контейнер для обработки этого класса как одиночного.

Вот очень упрощенный пример:

public class MyAppSettings : IAppSettings
{
    private readonly ObjectCache _cache = MemoryCache.Default;
    private readonly object _lock = new Object();
    private KeyValueClient _kvClient;

    public string MySecretValue => GetSecret("MySecretValue");

    private KeyValueClient GetKeyVaultClient()
    {
        // Initialize _kvClient if required

        return _kvClient;
    }

    private string GetSecret(string name)
    {
        lock (_lock)
        {
            if (_cache.Contains(key))
                return (string) _cache.Get(key);

            // Sanitize name if required, remove reserved chars

            // Construct path
            var path = "...";

            // Get value from KV

            var kvClient = GetKeyVaultClient();
            Task<SecretBundle> task = Task.Run(async() => await kvClient.GetSecretAsync(path));

            var value = task.Result;

            // Cache it
            _cache.Set(name, value, DateTime.UtcNow.AddHours(1));

            return value;
        }
    }
}

Это не готово к производству - вы 'Мне нужно будет изменить это и реализовать метод GetKeyVaultClient для фактического возврата вашего объекта KeyVaultClient, а также метод GetSecret должен санировать полученное имя ключа.

В нашем реестре DI эта настройка былаиспользуйте синглтон, подобный этому:

For<IAppSettings>().Use<MyAppSettings>().Singleton();

Эти два изменения, похоже, хорошо сработали для нас, и у нас не было никаких проблем с этим в течение некоторого времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...