设置 ViewStateUserKey 给我一个“视图状态 MAC 验证失败”错误
Posted
技术标签:
【中文标题】设置 ViewStateUserKey 给我一个“视图状态 MAC 验证失败”错误【英文标题】:Setting ViewStateUserKey gives me a "Validation of viewstate MAC failed" error 【发布时间】:2009-09-13 17:04:11 【问题描述】:我的 BasePage
类中有以下内容,我的所有 ASPX 页面都来自这些:
protected override void OnInit(EventArgs e)
base.OnInit(e);
ViewStateUserKey = Session.SessionID;
我还在Web.config
中设置了一个machineKey
。我不认为这个错误是因为网络农场,因为这也发生在我的开发机器上。
我的主机现已升级到 .NET 3.5 SP1。此次更新后,每次我使用上述ViewStateUserKey
设置进行编译时,每次回发时都会不断收到“Validation of viewstate MAC failed”错误。
我在这里做错了什么?在最新的框架更新中是否还需要此设置?
【问题讨论】:
【参考方案1】:好的 - 我迟到了一年的谈话 - 但这是正确的答案吗?这仅适用于经过身份验证的用户并且使用 ViewStateUserKey
作为用户名比会话 ID GUID 更容易猜测。
顺便说一句,如果您想在顶部“修复”代码,请使用会话 ID,但是您必须设置会话变量以使会话 ID 每次都停止更改。前任。
Session["Anything"] = DateTime.Now
ViewStateUserKey = Session.SessionID;
这当然是假设您要使用会话,否则您需要使用其他一些密钥,例如用户名或保存在 cookie 中的任何其他 guid。
【讨论】:
补充说明,有时我看到 sessionid 每次都在更改,直到使用会话,而其他时候会话 cookie 立即发送到客户端,而似乎没有使用会话。我还不是 100% 确定为什么会这样,但只是我注意到了。 这很有帮助。我不知道如果其中没有保存任何内容,ASP 不会保持会话。【参考方案2】:我已经进行了相当多的搜索以找到问题的确切原因。 Microsoft 的这篇文章确实有助于解释所有不同的原因。 http://support.microsoft.com/kb/2915218 原因 4 是我们登陆的无效 ViewStateUserKeyValue
将 ViewStateUserKey 设置为 Session.SessionID 或 User.Identity.Name 对我们不起作用。
由于以下原因,我们间歇性地收到验证错误。 当应用程序池被 IIS 重置时,会话实际上会被更新,从而导致错误。 我们在登录时删除 Session 以避免会话固定,也导致登录错误。
最终对我们有用的是基于 cookie 的解决方案,现在在 VS2012 中提供。
public partial class SiteMaster : MasterPage
private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
//First, check for the existence of the Anti-XSS cookie
var requestCookie = Request.Cookies[AntiXsrfTokenKey];
Guid requestCookieGuidValue;
//If the CSRF cookie is found, parse the token from the cookie.
//Then, set the global page variable and view state user
//key. The global variable will be used to validate that it matches in the view state form field in the Page.PreLoad
//method.
if (requestCookie != null
&& Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
//Set the global token variable so the cookie value can be
//validated against the value in the view state form field in
//the Page.PreLoad method.
_antiXsrfTokenValue = requestCookie.Value;
//Set the view state user key, which will be validated by the
//framework during each request
Page.ViewStateUserKey = _antiXsrfTokenValue;
//If the CSRF cookie is not found, then this is a new session.
else
//Generate a new Anti-XSRF token
_antiXsrfTokenValue = Guid.NewGuid().ToString("N");
//Set the view state user key, which will be validated by the
//framework during each request
Page.ViewStateUserKey = _antiXsrfTokenValue;
//Create the non-persistent CSRF cookie
var responseCookie = new HttpCookie(AntiXsrfTokenKey)
//Set the HttpOnly property to prevent the cookie from
//being accessed by client side script
HttpOnly = true,
//Add the Anti-XSRF token to the cookie value
Value = _antiXsrfTokenValue
;
//If we are using SSL, the cookie should be set to secure to
//prevent it from being sent over HTTP connections
if (FormsAuthentication.RequireSSL &&
Request.IsSecureConnection)
responseCookie.Secure = true;
//Add the CSRF cookie to the response
Response.Cookies.Set(responseCookie);
Page.PreLoad += master_Page_PreLoad;
protected void master_Page_PreLoad(object sender, EventArgs e)
//During the initial page load, add the Anti-XSRF token and user
//name to the ViewState
if (!IsPostBack)
//Set Anti-XSRF token
ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
//If a user name is assigned, set the user name
ViewState[AntiXsrfUserNameKey] =
Context.User.Identity.Name ?? String.Empty;
//During all subsequent post backs to the page, the token value from
//the cookie should be validated against the token in the view state
//form field. Additionally user name should be compared to the
//authenticated users name
else
//Validate the Anti-XSRF token
if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
|| (string)ViewState[AntiXsrfUserNameKey] !=
(Context.User.Identity.Name ?? String.Empty))
throw new InvalidOperationException("Validation of
Anti-XSRF token failed.");
Source
【讨论】:
能否请您详细说明一下?不仅是链接。 解释了为什么其他解决方案不适合我们。并将代码示例放在帖子上。 我目前正在尝试您的解决方案,目前看来效果不错。 我没有深入检查,但我想知道 web.config 的可选部分我现在通过将代码更改为:
protected override void OnInit(EventArgs e)
base.OnInit(e);
if (User.Identity.IsAuthenticated)
ViewStateUserKey = User.Identity.Name;
【讨论】:
@Druid 除了将上面的代码放在基页的 Oninit 事件中之外,我在这里也有同样的问题。我是否需要在任何子页面中设置 viewstateuserkey ..你能告诉我.. .. @pratapk 据我记得,没必要每页都设置。【参考方案4】:你能用 EnableViewStateMac @Page 属性关闭 ViewState MAC 编码吗?
【讨论】:
是的,如果我这样做,它会起作用。如果没有用,我宁愿删除 ViewStateUserKey 设置...【参考方案5】:很奇怪,我也有类似的问题 3 天,现在我解决了。 1. 我启用了表单身份验证并设置了 ssl false
<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" />
但在我的 httpcookies 标记中,我有 requireSSL=true。由于在 Site.Master.cs 中它使用 cookie 来设置 ViewStateUserKey,所以它遇到了问题
因此我得到了错误。
我将其修改为 false 并重新启动 web 应用程序,现在一切正常。
【讨论】:
以上是关于设置 ViewStateUserKey 给我一个“视图状态 MAC 验证失败”错误的主要内容,如果未能解决你的问题,请参考以下文章