Azure App Service多实例Data Protection密钥未找到问题求助
多实例Azure App Service下Data Protection密钥未找到异常的解决
问题背景
在双实例Azure App Service环境中,频繁触发Data Protection错误:密钥{xxxxxxxxxxx}在密钥环中未找到,Application Insights中堆积大量此类异常。重启实例可临时恢复,但问题会反复出现。
环境与配置
- 运行2个实例的Azure App Service
- 使用EF的
PersistKeysToDbContext存储Data Protection密钥,同时通过Azure Key Vault保护密钥 - 核心配置代码:
builder.Services.AddDataProtection() .SetApplicationName(dataProtectionOptions.ApplicationName) .PersistKeysToDbContext<DataProtectionKeyContext>() .ProtectKeysWithAzureKeyVault( new Uri(dataProtectionOptions.AzureKeyVaultKeyIdentifier!), new DefaultAzureCredential());
问题根源推测
ASP.NET Core Data Protection默认会将密钥环缓存到实例内存中,当其中一个实例生成新密钥并写入数据库后,其他实例仍在使用旧的缓存密钥环,导致无法解密新密钥加密的数据,从而抛出异常。
提问
有没有开发者遇到过用EF存储Data Protection密钥的多实例同步问题?如何确保所有实例能及时获取最新密钥?求可行的配置调整或最佳实践。
解决方案
1. 缩短密钥环缓存刷新间隔
默认缓存刷新周期是24小时,可通过SetKeyRingRefreshPeriod缩短间隔,让实例更频繁地从数据库拉取最新密钥,同时合理设置密钥生命周期:
builder.Services.AddDataProtection() .SetApplicationName(dataProtectionOptions.ApplicationName) .PersistKeysToDbContext<DataProtectionKeyContext>() .ProtectKeysWithAzureKeyVault( new Uri(dataProtectionOptions.AzureKeyVaultKeyIdentifier!), new DefaultAzureCredential()) // 设置密钥默认生命周期,按需调整(示例为7天) .SetDefaultKeyLifetime(TimeSpan.FromDays(7)) // 配置每5分钟刷新一次密钥环 .SetKeyRingRefreshPeriod(TimeSpan.FromMinutes(5));
注意:刷新间隔不宜过短,避免数据库请求量激增。
2. 临时禁用本地内存缓存(应急方案)
如果同步问题紧急,可强制实例每次从数据库读取密钥环,但会增加数据库负载,仅作为临时过渡方案:
builder.Services.AddDataProtection() .SetApplicationName(dataProtectionOptions.ApplicationName) .PersistKeysToDbContext<DataProtectionKeyContext>(options => { options.DisableLocalCache = true; }) .ProtectKeysWithAzureKeyVault( new Uri(dataProtectionOptions.AzureKeyVaultKeyIdentifier!), new DefaultAzureCredential());
3. 验证实例权限与配置一致性
- 确保所有App Service实例对存储Data Protection密钥的数据库拥有读写权限,避免出现实例无法写入/读取密钥的情况
- 确认所有实例的
SetApplicationName配置完全一致,这是框架识别同一应用集群的核心标识,名称不一致会导致各实例维护独立密钥环
4. 避免手动操作密钥数据
不要手动修改数据库中的Data Protection密钥记录,让框架自动管理密钥的生成、轮换和淘汰,手动干预极易破坏密钥环的一致性。
内容的提问来源于stack exchange,提问作者TIENTB
相关产品推荐
相关产品推荐

