【问题标题】:Key store providers cannot be set more than once (Always Encryption using Azure Function )密钥存储提供程序不能设置多次(始终使用 Azure 函数加密)
【发布时间】:2017-07-28 08:15:50
【问题描述】:

我已经实现了一个 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 作为我的密钥存储提供程序。我使用 AD 正确注册了我的 Keyvault,并将注册的应用程序添加到我的密钥库(访问策略)。

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

感谢您的回复,
贾延德兰

【问题讨论】:

  • 你在哪里调用你的InitializeAzureKeyVaultProvider() 方法?从错误消息中可以看出,您不止一次这样做了。

标签: c# azure azure-functions azure-keyvault always-encrypted


【解决方案1】:

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

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

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

【讨论】:

  • 最好只在应用程序启动、静态构造函数或类似的地方进行。像这样对静态属性进行变异将使您面临潜在的线程安全问题。
  • @Mikhail :现在我已经将我的初始化放在一个单独的类中并生成一个 DLL。这样我就可以在我的项目参考中添加 DLL 并在我的启动时调用。但不幸的是,它不起作用。我的方法对吗?
  • @JayendranRosh 应该可以。如果您遇到困难,请提出一个新问题,并附上重现问题的步骤。
  • @Mikhail 没关系。我得到了我的问题stackoverflow.com/questions/44965314/… 的答案。感谢您的快速回复
  • @MikhailShilkov 你能解释一下如何处理线程安全问题吗?
【解决方案2】:

我遇到了同样的问题,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.
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-24
    • 2023-02-01
    • 2022-07-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多