1

我已经实现了 TimeTriggerC# Azure 函数来运行存储过程以插入使用列加密加密的表(始终加密,AzureKey Vault 作为提供者)

对我来说,阻塞区域是我的函数 1 次成功运行,但又多次出错。所以我把成功之路作为一个罕见的案例

我面临的错误是

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作为我的 Key Store Provider。我使用 AD 正确注册了我的 Keyvault,并将注册的应用程序添加到我的密钥库(访问策略)。

为什么我会面临这种异常行为,比如一次成功,一次失败?

感谢您的回应,
杰恩德兰

4

2 回答 2

3

您可能InitializeAzureKeyVaultProvider()在每个函数调用中运行。如果第一次工作,则在此 App 实例上未执行初始化时。

在下一次函数调用期间,实例被重用,因此已经执行了初始化。但是您再次调用它,因此您会收到重复的注册错误。

要解决这个问题,请在静态构造函数中进行初始化,或者static bool无论您是否已经初始化,都存储一个标志 ( ),如果它是真的则跳过初始化(并注意线程安全)。

于 2017-07-28T08:25:57.840 回答
0

我遇到了与来自事件中心的消息触发的 Azure 函数相同的问题。

我的解决方案可能不是 100% 正确,但我不确定在令牌(来自 GetToken)到期后向提供者的注册是否会受到影响。所以我直到第一次调用需要 Azure Key Vault / Always Encrypted 的 SQL 查询时才注册。

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.
   }
}
于 2018-01-09T12:09:18.100 回答