Setting ViewStateUserKey gives me a “Validation of viewstate MAC failed” error

后端 未结 5 1891
清歌不尽
清歌不尽 2020-12-06 09:55

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

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


        
相关标签:
5条回答
  • 2020-12-06 10:35

    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/2915218 Cause 4 is what we have landed on which is an invalid ViewStateUserKeyValue

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

    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.

    What finally worked for us was a cookie based solution, which is now provided in 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

    0 讨论(0)
  • 2020-12-06 10:37

    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 ViewStateUserKey as the username is a lot easier to guess than a session 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

    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.

    0 讨论(0)
  • 2020-12-06 10:39

    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

    <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.

    0 讨论(0)
  • 2020-12-06 10:46

    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;
    }
    
    0 讨论(0)
  • 2020-12-06 10:56

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

    0 讨论(0)
提交回复
热议问题