2009-09-13 5 views
16

ich in meiner BasePage Klasse die folgende haben, welche alle meine ASPX-Seiten stammen aus:Einstellung ViewStateUserKey gibt mir ein „Validierung von Viewstate-MAC“ Fehler

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

Ich habe auch einen machineKey Satz in Web.config. Ich glaube nicht, dass dieser Fehler auf eine Webfarm zurückzuführen ist, weil dies auch auf meinem Dev-Rechner passiert.

Mein Host hat jetzt auf .NET 3.5 SP1 aktualisiert. Nach diesem Update erhalte ich jedes Mal, wenn ich mit der obigen Einstellung ViewStateUserKey kompiliere, ständig den Fehler "Validierung des Viewstate MAC failed" bei jedem Postback.

Was mache ich hier falsch? Ist diese Einstellung mit dem neuesten Framework-Update überhaupt noch notwendig?

Antwort

14

OK - Im ein Jahr zu spät, um das Gespräch - aber wie ist dies die richtige Antwort? Dies gilt nur für authentifizierte Benutzer und die Verwendung der ViewStateUserKey als Benutzername ist viel einfacher zu erraten als eine Sitzungs-ID GUID.

BTW Wenn Sie den Code nach oben "fixieren" möchten, verwenden Sie die Sitzungs-ID. Sie müssen jedoch eine Sitzungsvariable festlegen, damit sich die Sitzungs-ID nicht jedes Mal ändert. Ex. Session["Anything"] = DateTime.Now

ViewStateUserKey = Session.SessionID; 

Das ist natürlich vorausgesetzt, Sie Sitzungen verwenden werden, sonst hat man einen anderen Schlüssel müssen so verwenden, wie den Benutzernamen oder andere guid in einem Cookie gehalten.

+1

Eine Notiz hinzugefügt, manchmal sehe ich die Sitzungs-ID jedes Mal ändern, bis die Sitzung verwendet wird, und manchmal wird das Sitzungs-Cookie sofort an den Client gesendet, ohne die Sitzung scheinbar zu verwenden. Ich bin mir nicht 100% sicher, warum, aber ich habe es bemerkt. –

+0

Das war sehr hilfreich. Ich wusste nicht, dass ASP Sitzung nicht behält, wenn nichts darin gespeichert wird. – Reza

3

Können Sie ViewState MAC-Codierung mit dem EnableViewStateMac @ Page-Attribut deaktivieren?

+0

Ja, es funktioniert, wenn ich dies tun. Ich würde lieber die ViewStateUserKey Einstellung entfernen, wenn es keinen Nutzen hat ... – Druid

+0

Nun, wenn Sie den ViewStateUserKey loswerden funktioniert und Sie brauchen es nicht ... –

+1

True, aber es scheint Einstellung hilft dies gegen einen Klick (CSRF) Attacken ... – Druid

4

Ich reparierte es jetzt durch den Code zu ändern:

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

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

Ehrfürchtig, geben Sie selbst einen Scheck für die richtige Antwort. –

+1

@Druid Ich habe die gleiche Frage hier abgesehen von der oben genannten Code in Oninit Ereignis der Basis-Seite setzen .. Muss ich Viewstateuserkey in einer der untergeordneten Seiten ..Would Sie bitte sagen Sie mir .... –

+0

@Pratapk So weit Wie ich mich erinnere, ist es nicht notwendig, es auf jeder Seite einzustellen. – Druid

10

Ich habe ziemlich viel gesucht, um die endgültige Ursache des Problems zu finden. Dieser Beitrag von Microsoft hat wirklich geholfen, die verschiedenen Ursachen zu erklären. http://support.microsoft.com/kb/2915218 Ursache 4 ist das, was wir haben, auf dem gelandet ist eine ungültige ViewStateUserKeyValue

Einstellung ViewStateUserKey zu Session.SessionID oder User.Identity.Name nicht für uns nicht funktioniert.

Wir haben den Validierungsfehler aufgrund des Folgenden intermittierend erhalten. Wenn der Anwendungspool von IIS zurückgesetzt wird, wird die Sitzung erneuert, wodurch der Fehler verursacht wird. Wir löschen die Sitzung bei der Anmeldung, um eine Sitzungsfixierung zu vermeiden, was ebenfalls zu einem Fehler beim Login führt.

Was schließlich für uns funktionierte, war eine Cookie-basierte Lösung, die jetzt in VS2012 bereitgestellt wird.

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

Könnten Sie bitte mehr ausarbeiten? Nicht nur * Links *. – Kamiccolo

+4

Erklärt, warum die anderen Lösungen für uns nicht funktionierten. Und legen Sie das Codebeispiel auf den Post. – Vincejtl

+0

Ich versuche gerade deine Lösung und bisher scheint es, dass es gut funktioniert. – AFract

1

sehr seltsam, ich hatte zu ähnlichem Problem 3 Tage und ich es jetzt gelöst. 1. Ich hatte Formularauthentifizierung aktiviert und hatte ssl falsch

<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" /> 
  1. aber in meinem httpcookies Tag hatte ich RequireSSL = true. Seit dem in der Site.Master.cs es verwendet Cookies, um die ViewStateUserKey zu setzen, war es Probleme mit

  2. daher war ich den Fehler.

  3. Ich modifizierte dies zu false und neu gestartet Web-App, jetzt ist alles gut.