C# 设置 ViewStateUserKey 给我一个“视图状态 MAC 验证失败”错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1418233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 16:19:23  来源:igfitidea点击:

Setting ViewStateUserKey gives me a "Validation of viewstate MAC failed" error

c#asp.netasp.net-2.0viewstatefailed-to-load-viewstate

提问by Druid

I have the following in my BasePageclass which all my ASPX pages derive from:

我的BasePage班级中有以下内容,我所有的 ASPX 页面都源自:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    ViewStateUserKey = Session.SessionID;
}

I also have a machineKeyset in Web.config. I don't think this error is because of a web farm because this happens on my dev machine too.

我也machineKey有一套Web.config。我不认为这个错误是因为网络农场,因为这也发生在我的开发机器上。

My host has now upgraded to .NET 3.5 SP1. After this update, everytime I compile with the ViewStateUserKeysetting above, I constantly get the "Validation of viewstate MAC failed" error on every postback.

我的主机现已升级到 .NET 3.5 SP1。在此更新之后,每次我使用上述ViewStateUserKey设置进行编译时,我都会在每次回发时不断收到“视图状态 MAC 验证失败”错误。

What am I doing wrong here? Is this setting even necessary anymore with the latest framework update?

我在这里做错了什么?使用最新的框架更新,是否还需要此设置?

采纳答案by Adam Tuliper - MSFT

OK - Im a year late to the conversation - but how is this the correct answer? This applies only in the case of authenticated users and using the ViewStateUserKeyas the username is a lot easier to guess than a session id GUID.

好的 - 我的谈话晚了一年 - 但这是正确的答案吗?这仅适用于经过身份验证的用户的情况,并且将 用作用ViewStateUserKey户名比会话 ID GUID 更容易猜测。

BTW if you want to 'fix' the code up top, use the Session ID, however you must set a session variable in order for the session id to stop from changing every time. Ex. Session["Anything"] = DateTime.Now

顺便说一句,如果您想在顶部“修复”代码,请使用会话 ID,但是您必须设置一个会话变量,以便会话 ID 每次都停止更改。前任。 Session["Anything"] = DateTime.Now

ViewStateUserKey = Session.SessionID;

This of course is assuming you are going to use sessions, otherwise you need some other key to use such as the username or any other guid kept in a cookie.

这当然是假设您要使用会话,否则您需要使用其他一些密钥,例如用户名或保存在 cookie 中的任何其他 guid。

回答by David Andres

Can you turn off ViewState MAC encoding with the EnableViewStateMac @Page attribute?

您可以使用 EnableViewStateMac @Page 属性关闭 ViewState MAC 编码吗?

回答by Druid

I fixed it for now by changing the code to:

我现在通过将代码更改为:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    if (User.Identity.IsAuthenticated)
        ViewStateUserKey = User.Identity.Name;
}

回答by Vincejtl

I've searched around quite a bit to find the definitive cause of the issue. This post from Microsoft really helped explain all the different causes. http://support.microsoft.com/kb/2915218Cause 4 is what we have landed on which is an invalid ViewStateUserKeyValue

我已经搜索了很多以找到问题的确切原因。Microsoft 的这篇文章确实有助于解释所有不同的原因。 http://support.microsoft.com/kb/2915218原因 4 是我们发现的无效 ViewStateUserKeyValue

Setting ViewStateUserKey to Session.SessionID or User.Identity.Name did not work for us.

将 ViewStateUserKey 设置为 Session.SessionID 或 User.Identity.Name 对我们不起作用。

We intermittently got the validation error due to the following. When the application pool is reset by IIS, the session is renewed in effect causing the error. We drop the Session on login to avoid session fixation, also resulting in the error on login.

由于以下原因,我们间歇性地收到验证错误。当 IIS 重置应用程序池时,会话实际上会更新,从而导致错误。我们在登录时删除会话以避免会话固定,也会导致登录错误。

What finally worked for us was a cookie based solution, which is now provided in VS2012.

最终对我们有用的是基于 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

来源

回答by Sundara Prabu

VERY Strange, I too had similar issue for 3 days and now i resolved it. 1. I had enabled forms authentication and had ssl false

很奇怪,我也有类似的问题 3 天,现在我解决了。1.我启用了表单身份验证并且ssl false

<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" />
  1. but in my httpcookies tag I had requireSSL=true. Since in the Site.Master.cs it uses cookies to set the ViewStateUserKey, it was having issues

  2. hence I was getting the error.

  3. I modified this to false and restarted web app, now its all good.

  1. 但是在我的 httpcookies 标签中,我有 requireSSL=true。因为在 Site.Master.cs 中它使用 cookie 来设置 ViewStateUserKey,所以它有问题

  2. 因此我收到了错误。

  3. 我将其修改为 false 并重新启动了 Web 应用程序,现在一切正常。