密钥存储提供程序不能设置多次(始终使用Azure功能加密)

问题描述:

我已经实现了TimeTriggerC#Azure函数以运行存储过程插入使用列加密进行加密的表(始终加密,AzureKey保险库作为提供商)密钥存储提供程序不能设置多次(始终使用Azure功能加密)

对我来说,阻塞区域是我的函数在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的主要跳马我的密钥存储Provider.I正确注册我的AD Keyvault并添加已注册的应用程序到我的密钥保管库(访问策略)。

为什么我面对这种不正常的行为,像一次性成功和另一次失败?

感谢您回应,
Jayendran

+0

你在哪里调用'InitializeAzureKeyVaultProvider()'方法? 它从错误消息中看出您不止一次这样做。 – Max

您可能正在运行InitializeAzureKeyVaultProvider()每个函数调用里面。如果第一次工作,当这个App实例没有执行初始化。

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

要解决此问题,请在静态构造函数中进行初始化,或者存储标志(static bool)是否已经初始化,如果为true(并保证线程安全),则跳过初始化。

+1

更好的做法是在应用程序启动时使用静态构造函数或其他方法。像这样一个静态属性的变异会让你面对一个潜在的线程安全问题。 – Max

+0

@Mikhail:现在我已将初始化放在一个单独的类中,并生成了一个DLL。因此,我可以将该DLL添加到我的项目引用中,并在我的启动中调用。但不幸的是,它不工作。我的方式是否正确? – Jayendran

+0

@JayendranRosh应该工作。如果您遇到困难,请通过步骤重新提出问题,提出新问题。 – Mikhail

我遇到了来自进入事件中心的消息触发的Azure功能的相同问题。

我的解决方案可能不是100%正确的,但我不确定在令牌(来自GetToken)过期后,向提供者的注册是否会受到影响。所以我不会注册,直到我第一次调用需要Azure密钥保管库/始终加密的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. 
    } 
}