发布Azure Web应用更新后出现HttpAntiForgeryException的原因与解决办法
问题原因分析
这个HttpAntiForgeryException的核心诱因是ASP.NET防伪令牌的加密/验证密钥不统一,结合你的场景具体来说:
- 防伪令牌是由服务器端的加密密钥生成的,用户登录后,令牌会被存在浏览器Cookie中,后续提交请求时需要用相同的密钥解密验证。
- 你的应用运行在3个App Service实例的集群环境中,而升级前后大概率没有显式配置固定的全局密钥,用的是默认的
AutoGenerate模式。这种模式下,每个实例启动(或者每次发布重启)都会生成随机的本地密钥,导致:- 发布更新后,新实例的密钥和用户旧Cookie里令牌的加密密钥不匹配,解密失败;
- 即使开启了ARR Affinity(会话亲和),发布过程中部分实例先完成更新,用户请求路由到新实例时也会触发密钥不匹配的问题。
- 用户清除Cookie或重启浏览器后,会重新获取新密钥生成的令牌,所以问题暂时解决,但这只是临时方案,根源还是密钥的一致性问题。
解决方案
解决的核心就是为所有实例配置固定且全局一致的加密/验证密钥,确保发布前后、所有实例都用同一个密钥处理防伪令牌。下面是具体实现步骤:
1. 生成安全的密钥
首先需要生成符合要求的validationKey和decryptionKey,你可以用本地的C#代码生成(避免在线工具泄露密钥):
// 生成256位的validationKey(64个十六进制字符) var validationKey = System.Web.Security.MachineKey.GenerateKey(64); // 生成256位的decryptionKey(64个十六进制字符) var decryptionKey = System.Web.Security.MachineKey.GenerateKey(64);
- 注意:
validationKey对应SHA1算法至少需要40个字符,AES算法的decryptionKey至少需要32个字符,建议用最长的256位密钥提升安全性。
2. 配置密钥(推荐用Azure应用设置)
不建议把密钥硬编码到Web.config(源代码管理中容易泄露),推荐用Azure App Service的应用设置来存储:
- 登录Azure门户,找到你的Web App,进入「配置」→「应用设置」
- 添加两个应用设置:
- 名称:
MachineKey__ValidationKey,值:你生成的validationKey - 名称:
MachineKey__DecryptionKey,值:你生成的decryptionKey
- 名称:
- 然后修改项目中的
Web.config,在<system.web>节点下添加或修改<machineKey>配置,用占位符读取Azure的应用设置:
<system.web> <!-- 保留原有其他配置 --> <machineKey validation="SHA1" validationKey="%MachineKey__ValidationKey%" decryption="AES" decryptionKey="%MachineKey__DecryptionKey%" validationAlgorithm="SHA1" /> </system.web>
3. 验证修复效果
配置完成后重新发布应用:
- 已经有旧Cookie的用户可能会触发一次错误,但后续刷新页面会生成新的、用固定密钥加密的令牌,之后就不会再出现问题;
- 后续发布应用更新时,密钥不会因为实例重启或更新而改变,彻底解决集群环境下的防伪令牌解密问题。
内容的提问来源于stack exchange,提问作者Andrew Jocelyn
相关产品推荐
相关产品推荐

