2009-09-13 33 views
16

Tengo el siguiente en mi clase BasePage la que todos mis páginas ASPX derivar de:Configuración ViewStateUserKey me da una "Validación del estado de vista MAC falló" error

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

También tengo un conjunto machineKey en Web.config. No creo que este error se deba a una granja de servidores web porque esto también ocurre en mi máquina de desarrollo.

Mi host se ha actualizado a .NET 3.5 SP1. Después de esta actualización, cada vez que compilo con la configuración anterior ViewStateUserKey, constantemente obtengo el error "Validación de viewview MAC falló" en cada devolución.

¿Qué estoy haciendo mal aquí? ¿Ya es necesaria esta configuración con la última actualización del marco?

Respuesta

14

OK - Im un año de retraso a la conversación - ¿Pero cómo es la respuesta correcta? Esto se aplica solo en el caso de usuarios autenticados y usando el ViewStateUserKey, ya que el nombre de usuario es mucho más fácil de adivinar que un ID GUID de sesión.

BTW si quiere 'corregir' el código arriba, use la ID de la sesión, sin embargo, debe establecer una variable de sesión para que la identificación de la sesión deje de cambiar cada vez. Ex. Session["Anything"] = DateTime.Now

ViewStateUserKey = Session.SessionID; 

Por supuesto, esto es suponiendo que se va a utilizar sesiones, de lo contrario tienes alguna otra tecla para usar como el nombre de usuario o cualquier otro GUID guardado en una cookie.

+1

Una nota adicional, a veces veo que el sessionid cambia cada vez hasta que se usa la sesión, y otras veces la cookie de sesión se envía al cliente de inmediato sin usar aparentemente la sesión. Todavía no estoy 100% seguro de por qué, pero algo que he notado. –

+0

Esto fue muy útil. No sabía que ASP no mantiene la sesión si nada se guardaba en ella. – Reza

3

¿Puede desactivar la codificación MAC de ViewState con el atributo EnableViewStateMac @Page?

+0

sí, funciona si hago esto. Preferiría eliminar la configuración de ViewStateUserKey si no sirve ... – Druid

+0

Bueno, si deshacerse de la ViewStateUserKey funciona y no la necesita ... –

+1

Es cierto, pero parece que configurar esto ayuda contra un clic (CSRF)) ataques ... – Druid

4

me fijo es todo por ahora, cambiando el código para:

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

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

Impresionante, date un vistazo por la respuesta correcta. –

+1

@Druid Tengo la misma pregunta aquí, aparte de poner el código anterior en el evento Oninit de la página base ... ¿Necesito establecer viewstateuserkey en cualquiera de las páginas secundarias? ¿Podría decirme ... –

+0

@pratapk? según recuerdo, no hay necesidad de configurarlo en cada página. – Druid

10

He buscado bastante para encontrar la causa definitiva del problema. Esta publicación de Microsoft realmente ayudó a explicar las diferentes causas. http://support.microsoft.com/kb/2915218 Causa 4 es lo que hemos aterrizado en que es un inválido ViewStateUserKeyValue

Configuración ViewStateUserKey a Session.SessionID o User.Identity.Name no funcionó para nosotros.

Recibimos intermitentemente el error de validación debido a lo siguiente. Cuando IIS restablece el grupo de aplicaciones, la sesión se renueva y causa el error. Soltamos la sesión al iniciar sesión para evitar la fijación de la sesión, lo que también da como resultado el error al iniciar sesión.

Lo que finalmente funcionó para nosotros fue una solución basada en cookies, que ahora se proporciona en 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

¿Podría por favor, elaborar más? No solo * enlaces *. – Kamiccolo

+4

Explicado por qué las otras soluciones no nos funcionaron. Y pon el código de muestra en la publicación. – Vincejtl

+0

Actualmente estoy probando su solución y hasta ahora parece que funciona bien. – AFract

1

muy extraño, yo también tenía problema similar durante 3 días y ahora lo resolví. 1. que había permitido la autenticación de formularios y tenía ssl falsa

<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" /> 
  1. pero en mi httpcookies etiqueta que tenía requireSSL = true. Como en el Site.Master.cs utiliza cookies para establecer el ViewStateUserKey, que estaba teniendo problemas

  2. por lo tanto, que estaba recibiendo el error.

  3. Modifiqué esto a la aplicación web falso y reiniciado, ahora todo está bien.

Cuestiones relacionadas