Поставщики хранилища ключей не могут быть установлены более одного раза (всегда шифрование с использованием функции Azure)

Я реализовал функцию TimeTriggerC # Azure для запуска процедуры хранения для вставки таблицы, зашифрованной с использованием шифрования столбца (Always Encrypted, AzureKey Vault As Provider)

Область блокировки для меня заключается в том, что моя функция успешно выполнялась один раз и многократно повторяла ошибку. Так что путь успеха я получаю как редкий случай

Ошибка, с которой я столкнулся, это

mscorlib: исключение было выброшено целью вызова. System.Data: поставщики хранилища ключей не могут быть установлены более одного раза.

Я провел небольшое расследование по этому поводу. Это происходит в строке

SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);

В функции

static void InitializeAzureKeyVaultProvider()
{
    string clientId = ConfigurationManager.AppSettings["AuthClientId"];
    string clientSecret = ConfigurationManager.AppSettings["AuthClientSecret"];
    _clientCredential = new ClientCredential(clientId, clientSecret);

    // Direct the provider to the authentication delegate
    SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);

    Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers = new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
    providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);

    // register the provider with ADO.net
    SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
}

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

Исключение было создано целью вызова. ---> System.InvalidOperationException: поставщики хранилища ключей не могут быть установлены более одного раза. в System.Data.SqlClient.SqlConnection.RegisterColumnEncryptionKeyStoreProviders (IDictionary`2 customProviders)

Как я уже упоминал выше, я использовал Azure Key Vault в качестве поставщика хранилища ключей. Я правильно зарегистрировал свое хранилище ключей в AD и добавил зарегистрированное приложение в свое хранилище ключей (политики доступа).

Почему я сталкиваюсь с таким ненормальным поведением, как одноразовый успех и второй раз неудача?

Цените ваш ответ,
Джайендран


person Jayendran    schedule 28.07.2017    source источник
comment
Где вы вызываете свой InitializeAzureKeyVaultProvider() метод? Судя по сообщению об ошибке, вы делаете это более одного раза.   -  person Max    schedule 28.07.2017


Ответы (2)


Вероятно, вы используете InitializeAzureKeyVaultProvider() внутри каждого вызова функции. Если работает впервые, когда инициализация этого экземпляра приложения не выполнялась.

Во время следующего вызова функции экземпляр используется повторно, поэтому инициализация уже выполнена. Но вы вызываете его снова и получаете дублированную ошибку регистрации.

Чтобы решить эту проблему, выполните инициализацию в статическом конструкторе или сохраните флаг (static bool), независимо от того, инициализированы ли вы уже, и пропустите инициализацию, если это правда (и позаботьтесь о безопасности потоков).

person Mikhail Shilkov    schedule 28.07.2017
comment
Лучше просто сделать это при запуске приложения, статического конструктора или чего-то подобного. Подобное изменение статического свойства откроет вам целый мир потенциальных проблем безопасности потоков. - person Max; 28.07.2017
comment
@Mikhail: Теперь я поместил свою инициализацию в отдельный класс и построил для генерации DLL, чтобы я мог добавить DLL в свой справочник по проекту и вызвать свой запуск. Но, к сожалению, это не работает. Мой путь правильный? - person Jayendran; 20.12.2017
comment
@JayendranRosh Должно работать. Если вы застряли, задайте новый вопрос с инструкциями по воспроизведению проблемы. - person Mikhail Shilkov; 20.12.2017
comment
@Mikhail Неважно. Я получил ответ на свой вопрос stackoverflow.com/questions/44965314/. Спасибо за ваш быстрый ответ - person Jayendran; 20.12.2017
comment
@MikhailShilkov Не могли бы вы объяснить, как решать проблемы безопасности потоков? - person cbrawl; 18.04.2019

У меня возникла такая же проблема с функцией Azure, запускаемой из сообщений, поступающих в концентратор событий.

Мое решение, вероятно, не на 100% правильное, но я не уверен, что это повлияет на регистрацию у поставщика после истечения срока действия токена (из GetToken). Поэтому я не регистрируюсь до тех пор, пока в первый раз не вызову SQL-запрос, для которого требуется Azure Key Vault / Always Encrypted.

try
{
   cmd.ExecuteNonQuery();
}
catch (System.ArgumentException ex)
{
   if (ex.TargetSite.Name == "DecryptSymmetricKey" && ex.InnerException == null)
   {
                    InitializeAzureKeyVaultProvider() //Register the Provider
                    cmd.ExecuteNonQuery(); // Try the query again.
   }
}
person Rob Barat    schedule 09.01.2018