Azure Function结合Azure Key Vault实现SQL Always Encrypted列加密问题咨询
解决方案
无应用注册的Azure Key Vault访问配置
你第二种基于Azure.Identity凭证类的实现思路本身是正确的,完全不需要创建Azure应用注册资源:
- 本地开发场景下,
VisualStudioCredential会自动读取你当前VS登录的Azure账号身份,只要给该账号分配AKV的「密钥加密、密钥解密、密钥打包、密钥解包」四个密钥权限,或是直接分配「Key Vault Crypto User」RBAC角色即可正常认证 - 线上Azure Function运行场景下,
ManagedIdentityCredential会自动调用Function绑定的系统分配/用户分配托管身份,给对应托管身份分配和上面一样的AKV权限即可,无需任何密钥配置。如果使用用户分配托管身份,只需给ManagedIdentityCredential构造函数传入托管身份的客户端ID参数即可。
旧代码中基于ClientCredential的实现是已过时的认证方式,现在官方原生支持直接传入Azure.Identity的TokenCredential实现类来初始化SqlColumnEncryptionAzureKeyVaultProvider,完全规避应用注册相关的配置。
依赖冲突报错修复
你遇到的Method not found类报错是典型的Azure Functions运行时依赖版本冲突问题,Azure Functions进程内运行模型自带固定版本的Microsoft.Extensions.*系列类库,手动安装更高版本的对应包就会触发该类异常,修复步骤如下:
进程内(In-Process)模型修复
- 删除所有你手动显式安装的
Microsoft.Extensions.*开头的NuGet包 - 统一使用5.1.x及以上稳定版的
Microsoft.Data.SqlClient和Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider包,该版本已经完成了和Azure.Identity的适配优化 - 如果必须使用特定版本的
Microsoft.Extensions类库,在项目的.csproj文件中添加配置,强制运行时使用项目内的包版本:
<ItemGroup> <FunctionsPreservedDependencies Include="Microsoft.Extensions.*" /> </ItemGroup>
独立Worker(Isolated)模型修复
独立Worker模型不存在运行时共享依赖的冲突问题,只需将所有Microsoft.Azure.Functions.Worker.*相关包升级到最新稳定版即可正常使用。
按上述配置调整后,你之前删除ILogger绕过报错的操作也可以回滚,原生ILogger可以正常使用。
修正后的可用初始化代码示例
using Azure.Identity; using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider; using System; using System.Collections.Generic; using System.Diagnostics; private static bool EncryptionProviderInitialized = false; private static void InitializeAzureKeyVaultProvider() { if (EncryptionProviderInitialized) return; SqlColumnEncryptionAzureKeyVaultProvider akvProvider = null; #if DEBUG if (Debugger.IsAttached) { // 本地测试可依次尝试VS凭证、CLI凭证、PowerShell凭证,适配不同开发环境 var localCredential = new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeManagedIdentityCredential = true, ExcludeEnvironmentCredential = true }); akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(localCredential); } #endif akvProvider ??= new SqlColumnEncryptionAzureKeyVaultProvider(new ManagedIdentityCredential()); // 若使用用户分配托管身份,替换为下面的代码,替换为对应托管身份的客户端ID // akvProvider ??= new SqlColumnEncryptionAzureKeyVaultProvider(new ManagedIdentityCredential("your-user-assigned-mi-client-id")); SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders: new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase) { { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvProvider } }); EncryptionProviderInitialized = true; }
内容的提问来源于stack exchange,提问作者Klh
相关产品推荐
相关产品推荐

