IIS服务器Machine Key加密验证失效及会话超时问题求助
问题概述
部署在IIS上的应用,原采用SHA1及自动加密验证方式运行正常,单台服务器突然出现两类异常:
- 应用陷入重定向循环,事件日志抛出如下错误:
Unable to validate data.
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo, Boolean signData)
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType)
at System.Web.UI.Page.EncryptStringWithIV(String s, IVType ivType)
at System.Web.Handlers.AssemblyResourceLoader.FormatWebResourceUrl(String assemblyName, String resourceName, Int64 assemblyDate, Boolean htmlEncoded)
at System.Web.Handlers.AssemblyResourceLoader.GetWebResourceUrlInternal(Assembly assembly, String resourceName, Boolean htmlEncoded)
at System.Web.Handlers.AssemblyResourceLoader.GetWebResourceUrl(Type type, String resourceName, Boolean htmlEncoded)
at System.Web.UI.ClientScriptManager.RegisterClientScriptResource(Type type, String resourceName)
at System.Web.UI.WebControls.BaseValidator.RegisterValidatorCommonScript()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Control.PreRenderRecursiveInternal()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
- 修改Machine Key加密与验证算法后应用恢复,但随即触发会话超时,事件日志报错:
Event code: 4005
Event message: Forms authentication failed for the request. Reason: The ticket supplied has expired.
Event time: 04/09/2023 4:45:38 PM
Event time (UTC): 04/09/2023 11:15:38 AM
Event ID: d84f9a41a0a1404e97a3fe7568ce0943
Event sequence: 2142
Event occurrence: 53
Event detail code: 50202
相同应用在其他服务器运行正常,以下是根因分析及解决方案。
根因分析
1. 「Unable to validate data」与重定向循环
- 当应用设置为自动生成Machine Key时,服务器会在应用池回收、IIS重启或配置变更时重新生成随机密钥。
- 该服务器的Machine Key意外触发了重新生成(例如应用池意外回收、系统更新导致IIS重启),但客户端缓存的
WebResource.axd等加密资源链接是用旧密钥生成的,服务器用新密钥验证时失败,抛出「Unable to validate data」错误。 - 错误触发后,应用异常处理逻辑将请求重定向到错误页/登录页,而这些页面本身需要加载加密客户端资源,再次触发验证失败,形成循环。
2. 修改Machine Key后的会话超时
- 修改Machine Key的加密/验证算法后,服务器无法解密之前用SHA1算法生成的Forms Authentication Ticket(存储在Cookie中),会直接判定票据无效并标记为「过期」,触发Event Code 4005报错。
- 其他服务器未修改Machine Key,仍使用原算法和自动生成的密钥(或一致的手动配置密钥),能正常解密旧票据,因此无超时问题。
解决方案
针对「Unable to validate data」与重定向循环
- 统一配置手动Machine Key:在所有部署该应用的服务器的
web.config中配置相同的固定Machine Key,禁用自动生成。示例配置:
<system.web> <machineKey validationKey="生成的固定随机密钥" decryptionKey="生成的固定随机密钥" validation="SHA1" decryption="Auto" /> </system.web>
密钥可通过aspnet_regiis.exe -gk命令安全生成,确保所有服务器的密钥完全一致。
针对会话超时问题
- 多算法兼容过渡:若必须更换加密/验证算法,可在
web.config的machineKey中配置多算法支持,让服务器优先用新算法验证,失败后再尝试旧算法,兼容旧票据:
<machineKey validationKey="固定密钥" decryptionKey="固定密钥" validation="HMACSHA256,SHA1" decryption="AES" />
- 强制重新登录:若无需兼容旧票据,可通知用户清除浏览器Cookie或重新登录,新生成的票据会使用新算法加密,不再触发过期错误。
- 同步服务器时间:确保所有应用服务器的系统时间一致,时间差过大也会导致Forms Authentication Ticket被误判为过期。
内容的提问来源于stack exchange,提问作者Pratik Wakati

