我的BasePage
课程中有以下内容,我的所有ASPX页面都来自:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
ViewStateUserKey = Session.SessionID;
}
我在machineKey
中设置了Web.config
。我不认为这个错误是因为Web场,因为这也发生在我的开发机器上。
我的主机现已升级到.NET 3.5 SP1。在此更新之后,每次使用上面的ViewStateUserKey
设置进行编译时,我都会在每次回发时不断获得“viewstate MAC failed”验证错误。
我在这里做错了什么?使用最新的框架更新,这个设置是否更加必要?
答案 0 :(得分:16)
好的 - 我的谈话迟了一年 - 但这怎么回答正确?这仅适用于经过身份验证的用户并使用ViewStateUserKey
,因为用户名比会话ID GUID更易于猜测。
顺便说一句,如果你想“修复”代码,请使用会话ID,但是你必须设置一个会话变量,以便会话ID不再每次都改变。防爆。
Session["Anything"] = DateTime.Now
ViewStateUserKey = Session.SessionID;
这当然是假设您要使用会话,否则您需要使用其他密钥,例如用户名或cookie中保存的任何其他guid。
答案 1 :(得分:10)
我已经搜索了很多,以找到问题的确切原因。 微软的这篇文章真的帮助解释了所有不同的原因。 http://support.microsoft.com/kb/2915218 原因4是我们登陆的无效ViewStateUserKeyValue
将ViewStateUserKey设置为Session.SessionID或User.Identity.Name对我们不起作用。
由于以下原因,我们间歇性地得到了验证错误。 当IIS重置应用程序池时,会话将更新,从而导致错误。 我们在登录时删除会话以避免会话固定,也导致登录时出错。
最终为我们工作的是基于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.");
}
}
}
}
答案 2 :(得分:4)
我现在通过将代码更改为:
来修复它protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (User.Identity.IsAuthenticated)
ViewStateUserKey = User.Identity.Name;
}
答案 3 :(得分:3)
您可以使用EnableViewStateMac @Page属性关闭ViewState MAC编码吗?
答案 4 :(得分:1)
非常奇怪,我也有类似的问题3天,现在我解决了。 1.我启用了表单身份验证并使用了ssl false
<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" />
但在我的httpcookies标签中,我有requireSSL = true。因为在Site.Master.cs中它使用cookie来设置ViewStateUserKey,所以它有问题
因此我收到了错误。
我将此修改为false并重新启动了网络应用,现在一切都很好。