一个有趣的 ”Validation of viewstate MAC failed” 错误的发现和解决
在ASP.NET里面,View State使用较为广泛。它作为一个隐藏字段,可以帮助服务端”记住“客户端的改变,这样客户端 收到服务器对PostBack的响应后,仍然可以展现在PostBack之前设定的值 (具体参见http://msdn.microsoft.com/en-us/library/bb386448(v=vs.100).aspx )
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="..." />
为了防止恶意客户端的PostBack里的ViewState被解读,ASP.NET会用消息验证码(MAC)来检查每个ViewState。可是一旦服务器无法正确解释正常客户端PostBack回来的ViewState时,整个应用都会停止工作。比如出现 ”Validation of viewstate MAC failed” 的错误。
通常来说,一旦这样的错误出现,首先会考虑以下几种情况:
1. 是不是有多台Web Server在负载均衡情况下运行。如果是的话,需要各台服务器使用相同的MAC进行ViewState的加密和解密工作。否则如果这个负载均衡环境没有完全做的Session Affinity,这种错误就会出现。
2. 测试本机访问是否也有这种错误。如果是的话,除了尝试重新产生新的MachineKey (参见http://blogs.msdn.com/b/amb/archive/2012/07/31/easiest-way-to-generate-machinekey.aspx ),也可以用Process Monitor在复现问题的时候跟踪文件和注册表的访问,看看是不是因为W3WP.exe缺少权限而不能获取和MachineKey相关的信息。
3. 在客户端和服务器端抓取网络包,比较ViewState是否被中间设备改动。这种情况不多见,但是也遇到过。算是复杂的一种情况。如果连接是SSL的,抓包没有办法查看,客户端就要使用Fiddler,而服务端需要采取额外诊断日志或者Debug的方法。
4. 和具体代码相关,尤其是对ViewStateUserKey有特殊设置。
这里谈到的是一个在一个大型的生产应用环境里遇到的实际问题,和上面的情况有关,但有些有趣的变化。
这个环境里面有多台Web 服务器,采用了负载均衡方式。在客户试图登录时(login.aspx),总是会遇到”Validation of viewstate MAC failed”的错误。
起初,怀疑是不同机器上WebAppication的MachineKey不一样引起的。检查了Web.Config里的配置,各个机器都是一样:
<system.web> <machineKey decryptionKey="6284D74F8D9745C38712047622FFA047B02CA5C4049FB74E,IsolateApps" validationKey="137B974DC38A910D946AAF3ADF1D0386072170236F39C8165098035126FE7DFDF68C7BD3646052CE1769A47A45F098A65CEC3089523543370DD37830A5B2D13,IsolateApps" /> </system.web>
而且负载均衡也设置了Class C的Session Affinity
后来发现这个问题即使本机访问也会出现。把应用程序池身份改为Admin后,问题同样。表明和权限无关。重新创建MachineKey,也没有变化。
这时需要关注代码。获取了页面代码做Review. 在Login页面的Page_Init里面, 看到ViewStateUserKey
protected void Page_Init(object sender, EventArgs e)
{
this.ViewStateUserKey = this.Session.SessionID;
}
表面上看这样的写法也没有什么问题。
在IE上启用了Fiddler (连接是SSL) 后,发现客户端的PostBack里面没有Cookie的信息。这就是问题出现的直接原因:
a. 在第一次访问Login页面时,用一个随机的SessionID A被嵌入了ViewState里面
b. 在PostBack时,由于没有Cookie传回来(ASP.NET SessionID缺省存放在Cookie里),服务器就判断道客户端没有SessionID, 于是又使用一个新的SessionID B做ViewStateUserKey. 这样,从ViewState里面解出的是上次的SessionID A, 和新的不匹配。错误就出现了。
可是客户端为什么不发送Cookie呢?
原来这个服务器第一次回复时,对客户端的HTTP Header里面根本没有Set-Cookie字段。
这是没有赋予Session 变量时ASP.NET的缺省行为 ( SessionID每次请求都会形成,但是未必会发送Set-Cookie 来让客户端保留这个SessioID,除非有赋予Session变量的行为)
于是解决这个问题的直接方法就是在这个Page_Init里面第一时间加一个语句:
protected void Page_Init(object sender, EventArgs e)
{
this.ViewStateUserKey = this.Session.SessionID;
session("forViewSate")="value" }
这样服务器把SessionID在”Set-Cookie”里发送回去,客户端也可以用Cookie保留SessionID。问题就立刻解决了。
更多参考:
微软技术文章讨论如何处理” ”Validation of viewstate MAC failed”:
http://support.microsoft.com/kb/2915218
一个有趣的 ”Validation of viewstate MAC failed” 错误的发现和解决的更多相关文章
- ”Validation of viewstate MAC failed” 错误
”Validation of viewstate MAC failed” 错误 在ASP.NET里面,View State使用较为广泛.它作为一个隐藏字段,可以帮助服务端”记住“客户端的改变,这样客户 ...
- 转:Validation of viewstate MAC failed异常的原因及解决方法
ViewState是一种机制,ASP.NET 使用这种机制来跟踪服务器控件状态值,否则这些值将不作为 HTTP 窗体的一部分而回传.也就是说在页面刷新或者回传的时候控件的值将被清空,我们在aspx.c ...
- Validation of viewstate MAC failed. 解决方法
前段时间公司为了减轻服务器压力,对网页做了集群,分布在多台服务器,通过DNS轮回解析到各台服务器,结果页面只要打开停留到DNS解析到下一个地址,就会出现出下错误信息. Validation of vi ...
- Validation of viewstate MAC failed machinekey生成、使用方法
前段时间公司为了减轻服务器压力,对网页做了集群,分布在多台服务器,通过DNS轮回解析到各台服务器,结果页面只要打开停留到DNS解析到下一个地址,就会出现出下错误信息. Validation of vi ...
- Validation of viewstate MAC failed 解决办法
大部分人都说是在页里或web.config里加EnableEventValidation="false" EnableViewStateMac="false" ...
- 【问题收集·知识储备】Xcode只能选择My Mac,不能选择模拟器如何解决?
网友问题:请问打开一个应用,只能选择My Mac,不能选择模拟器如何解决? 答案: 下面将问答过程记录如下: CHENYILONG Blog 请问打开一个应用,只能 ...
- 关于安装teamviewer11出现verification of your teamviewer version failed错误处理
关于安装teamviewer11出现verification of your teamviewer version failed错误处理 teamviewer 在ubuntu 中安装方法是: 去tea ...
- 【小贴士】关于transitionEnd/animate的一个有趣故事
前言 在很久之前,我们项目有一个动画功能,功能本身很简单,便是典型的右进左出,并且带动画功能 以当时来说,虽然很简单,但是受限于框架本身的难度,就直接使用了CSS3的方式完成了功能 当时主要使用tra ...
- 一个有趣的SQL Server 层级汇总数据问题
看SQL Server大V宋大侠的博客文章,发现了一个有趣的sql server层级汇总数据问题. 具体的问题如下: parent_id emp_id emp_nam ...
随机推荐
- alpha版出炉,实现win2008 service的session 0穿透
指定用户名,拿最小session,实现和用户ui交互. 这样,搞windows的自动化部署,就可以向前一大步啦. 比以前用psexec要用户名密码,指定session要先进多啦. 安全保密性也提高了. ...
- DJANGO中正规的建立与USER外键的方式
以前都是直接与user 最近看书,上说settings.AUTH_USER_MODEL,这样好些...是为记. from django.db import models from django.con ...
- Vim tips——Working with external commands
A common sequence of events when editing files is to make a change and then need to test by executin ...
- 1.求整数最大的连续0的个数 BinaryGap Find longest sequence of zeros in binary representation of an integer.
求整数最大的连续0的个数 A binary gap within a positive integer N is any maximal sequence of consecutive zeros t ...
- 如何定义StrokeIt手势 常用StrokeIt手势大全
1 最小化,最大化,最小化所有(显示桌面) 斜向上表示最大化或者还原,斜向下表示最小化,适用于任务管理器和一般应用程序(有这三个按钮的都可以),先斜向下再斜向上表示显示桌面,这个在WIN7系统中不太实 ...
- LeetCode OJ 322. Coin Change DP求解
题目链接:https://leetcode.com/problems/coin-change/ 322. Coin Change My Submissions Question Total Accep ...
- Apache Kafka-0.8.1.1源代码编译
作者:过往记忆 | 新浪微博:左手牵右手TEL | 能够转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明博客地址:http://www.iteblog.com/文章标题:<Apac ...
- 【JavaScript】JS读取XML文件并进行搜索
需求效果 点击链接.当前页面载入xml文件并展示相应内容 通过搜索框.搜索xml文件内节点数据.展示包括内容的节点数据 功能实现 Demo终于实现效果 http://loadxmldemo.coder ...
- 杂项-Java:JMX
ylbtech-杂项-Java:JMX 1.返回顶部 1. JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序.设备.系统等植入管理功能的框架.JMX可 ...
- bzoj3132
二维树状数组 树状数组什么的只支持修改单个数值,但是这道题要我们更新一个区域 盗图 就是这样,然后维护四个bit就行了 #include<bits/stdc++.h> using name ...