2009-09-13 6 views
16

je suit dans ma classe qui BasePage toutes mes pages ASPX proviennent:Réglage ViewStateUserKey me donne une "validation de MAC viewstate a échoué" erreur

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

J'ai aussi un machineKey ensemble dans Web.config. Je ne pense pas que cette erreur soit due à une ferme web car cela se passe aussi sur ma machine de développement. Mon hôte a maintenant mis à niveau vers .NET 3.5 SP1. Après cette mise à jour, chaque fois que je compile avec le paramètre ViewStateUserKey ci-dessus, je reçois constamment l'erreur «Validation de MAC viewstate a échoué» sur chaque publication.

Qu'est-ce que je fais mal ici? Ce réglage est-il encore nécessaire avec la dernière mise à jour du framework?

Répondre

14

OK - Im un an de retard à la conversation - mais comment est-ce la bonne réponse? Cela s'applique uniquement dans le cas des utilisateurs authentifiés et en utilisant le ViewStateUserKey car le nom d'utilisateur est beaucoup plus facile à deviner qu'un GUID d'identification de session. Si vous voulez corriger le code en haut, utilisez l'ID de session, mais vous devez définir une variable de session pour que l'identifiant de session cesse de changer à chaque fois. Ex. Session["Anything"] = DateTime.Now

ViewStateUserKey = Session.SessionID; 

Bien sûr, suppose que vous allez utiliser les sessions, sinon vous avez besoin d'une autre clé à utiliser comme le nom d'utilisateur ou tout autre guid conservé dans un cookie.

+1

Une note ajoutée, parfois je vois le changement de session chaque fois que la session est utilisée, et d'autres fois le cookie de session est envoyé au client immédiatement sans apparemment utiliser la session. Je ne suis pas sûr à 100% pourquoi encore sur ce point mais juste quelque chose que j'ai remarqué. –

+0

C'était très utile. Je ne savais pas que ASP ne garde pas la session si rien ne l'a sauvegardé. – Reza

3

Pouvez-vous désactiver le codage MAC ViewState avec l'attribut EnableViewStateMac @Page?

+0

Oui, il fonctionne si je fais cela. Je préfèrerais supprimer le paramètre ViewStateUserKey s'il ne sert à rien ... – Druid

+0

Eh bien, si vous vous débarrassez de ViewStateUserKey et que vous n'en avez pas besoin ... –

+1

Vrai, mais il semble que cela aide à éviter un clic (CSRF) attaques ... – Druid

4

Je l'ai fixé pour l'instant en changeant le code:

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

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

Génial, donnez-vous un chèque pour la bonne réponse. –

+1

@Druid J'ai la même question ici en dehors de mettre le code ci-dessus dans l'événement Oninit de la page de base .. Dois-je définir viewstateuserkey dans l'une des pages enfant .. S'il vous plaît dites-moi .... –

+0

@pratapk Jusqu'à présent si je me souviens, il n'est pas nécessaire de le mettre sur chaque page. – Druid

10

J'ai cherché un peu pour trouver la cause définitive du problème. Ce message de Microsoft a vraiment contribué à expliquer toutes les différentes causes. http://support.microsoft.com/kb/2915218 Cause 4 est ce que nous avons atterri sur ce qui est un ViewStateUserKeyValue invalide

Réglage ViewStateUserKey à Session.SessionID ou User.Identity.Name ne fonctionne pas pour nous.

Nous avons reçu par intermittence l'erreur de validation en raison de ce qui suit. Lorsque le pool d'applications est réinitialisé par IIS, la session est renouvelée en effet provoquant l'erreur. Nous abandonnons la session lors de la connexion pour éviter la fixation de la session, ce qui entraîne également une erreur lors de la connexion. Ce qui a finalement fonctionné pour nous était une solution basée sur les cookies, qui est maintenant fournie dans 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

Pourriez-vous s'il vous plaît, élaborer plus? Non seulement * liens *. – Kamiccolo

+4

Expliqué pourquoi les autres solutions n'ont pas fonctionné pour nous. Et mettre l'échantillon de code sur le post. – Vincejtl

+0

Je suis actuellement en train d'essayer votre solution et pour l'instant, il semble que cela fonctionne bien. – AFract

1

très étrange, moi aussi eu problème similaire pendant 3 jours et maintenant je l'a résolu. 1. J'avais permis l'authentification des formulaires et avait ssl faux

<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" /> 
  1. mais dans mon tag httpcookies j'avais requireSSL = true. Depuis dans le Site.Master.cs utilise les cookies pour définir le ViewStateUserKey, il avait des problèmes

  2. où je recevais l'erreur. Je l'ai modifié pour faux et a redémarré l'application Web, maintenant tout est bon.

Questions connexes