负载均衡场景下AutoGenerate,IsolateApps类型MachineKey迁移方案咨询
负载均衡场景下MachineKey兼容方案解析
刚好处理过类似的生产环境问题,给你梳理清楚当前的问题和可行的解决方案:
一、当前AutoGenerate配置在负载均衡下的必现问题
你现在用的<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps" .../>,本质是每个应用程序池会自动生成唯一的密钥,而且不同服务器(甚至同一服务器不同应用池)的密钥完全独立。启用负载均衡后,会直接导致两个核心问题:
- 用户登录状态、表单验证票、视图状态这类依赖MachineKey的内容,跨服务器访问时会直接失效(比如用户在服务器A登录,跳转到服务器B就会被强制退出)
- 你用
MachineKey.Protect/Unprotect处理的加密数据,在不同服务器上根本无法解密,因为密钥不统一
所以这个配置绝对不能在负载集群里用,必须统一密钥,但直接换静态密钥又会导致旧数据解密失败,得用兼容方案。
二、兼容旧加密数据的两种可行方案
方案1:提取现有自动生成密钥,统一配置到所有服务器(最推荐)
AutoGenerate的密钥并不是凭空消失的,它会存在服务器的注册表中,你可以把当前应用在用的密钥提取出来,作为静态密钥配置到所有集群服务器上,这样既保留了对旧加密数据的兼容性,又能满足负载均衡的密钥统一要求。
具体操作步骤:
- 打开当前运行应用的服务器的注册表编辑器(运行
regedit即可) - 导航到对应.NET版本的AutoGenKeys路径:
- 如果你用的是.NET 4.x,路径是
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\4.0.30319.0\AutoGenKeys - .NET 2.x的话是
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0\AutoGenKeys
- 如果你用的是.NET 4.x,路径是
- 在这个路径下,找到对应你应用程序池的密钥项:名称格式是
App_{应用程序池GUID}_ValidationKey和App_{应用程序池GUID}_DecryptionKey - 复制这两个项的密钥值,替换到web.config的machineKey节点中,去掉
AutoGenerate,IsolateApps,改成静态配置,比如:<machineKey validationKey="这里粘贴提取到的ValidationKey" decryptionKey="这里粘贴提取到的DecryptionKey" validation="SHA1" decryption="Auto" /> - 把这个更新后的web.config部署到负载集群的所有服务器上,这样所有服务器用的都是原来的密钥,旧加密数据能正常解密,负载均衡下的会话、视图状态也能跨服务器正常工作。
方案2:双密钥兼容(适合需要更换新密钥的场景)
如果出于安全考虑,你不想继续用原来的自动生成密钥,想要换成自己指定的新密钥,同时又要兼容旧数据,可以实现自定义的密钥提供器,让系统解密时先尝试用新密钥,失败再用旧密钥,之后再逐步迁移加密数据到新密钥。
大致步骤:
- 先按方案1的方法提取出旧的自动生成密钥
- 自定义一个继承自
MachineKeyProvider的类,在解密逻辑里先使用新密钥尝试解密,解密失败则 fallback 到旧密钥 - 在web.config中配置使用这个自定义密钥提供器,并同时配置新旧两个密钥
- 后续可以分批将已有的加密数据重新用新密钥加密,完成迁移后再移除旧密钥的支持
这个方案相对复杂,除非有更换密钥的硬性需求,否则方案1是最省心直接的。
三、验证方案有效性
配置完成后,一定要做这几个验证:
- 在负载均衡的不同服务器上测试用户登录状态,确认跨服务器访问时不会被强制退出
- 找一些之前用
MachineKey.Protect加密的数据,测试是否能正常用MachineKey.Unprotect解密 - 测试新加密的数据,在不同服务器上都能正常解密
内容的提问来源于stack exchange,提问作者user3711357
相关产品推荐
相关产品推荐

