2009-09-13 5 views
16

Mam następujące klasy w moim BasePage którym wszystkie moje strony aspx pochodzić:Ustawianie ViewStateUserKey daje mi „Validation of viewstate MAC nie powiodło się” błąd

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

Mam też machineKey zestaw w Web.config. Nie sądzę, że ten błąd wynika z farmy internetowej, ponieważ dzieje się tak również na moim komputerze.

Mój komputer został zaktualizowany do .NET 3.5 SP1. Po tej aktualizacji za każdym razem, gdy kompiluję się z powyższym ustawieniem ViewStateUserKey, ciągle otrzymuję komunikat o błędzie "Sprawdzanie poprawności adresu MAC nie powiodło się" przy każdym odświeżeniu.

Co ja tu robię źle? Czy to ustawienie jest nawet konieczne przy najnowszej aktualizacji ramowej?

Odpowiedz

14

OK - Im roku późno na rozmowę - ale jak to jest prawidłowa odpowiedź? Dotyczy to tylko uwierzytelnionych użytkowników i korzystania z ViewStateUserKey, ponieważ nazwa użytkownika jest łatwiejsza do odgadnięcia niż identyfikator GUID identyfikatora sesji.

BTW, jeśli chcesz, aby „naprawić” kod górę górze, użyj identyfikatora sesji, jednak należy ustawić zmienną sesji, aby identyfikator sesji, aby zatrzymać zmianę za każdym razem. Dawny. Session["Anything"] = DateTime.Now

ViewStateUserKey = Session.SessionID; 

to oczywiście przy założeniu, że masz zamiar użyć sesji, w przeciwnym razie trzeba trochę inny klucz do używania, takie jak nazwa użytkownika lub innych GUID przechowywane w pliku cookie.

+1

Dodana uwaga, czasami widzę zmianę sessionid za każdym razem, dopóki sesja nie jest używana, i innym razem ciasteczko sesji jest wysyłane do klienta natychmiast bez pozornie korzystania z sesji. Nie jestem w 100% pewny, dlaczego jeszcze na tym, ale po prostu coś zauważyłem. –

+0

To było bardzo pomocne. Nie wiedziałem, że ASP nie zatrzymuje sesji, jeśli nic w niej nie jest zapisane. – Reza

3

można wyłączyć kodowanie ViewState MAC z EnableViewStateMac @Page atrybut?

+0

Tak, to działa, czy mogę to zrobić. Wolę usunąć ustawienie ViewStateUserKey, jeśli to nie ma sensu ... – Druid

+0

Cóż, jeśli pozbędzie się ViewStateUserKey działa i nie jest ci potrzebny ... –

+1

Prawda, ale wygląda na to, że ustawienie pomaga w jednym kliknięciu (CSRF) ataki ... – Druid

4

Naprawiłem go teraz przez zmianę kodu do:

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

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

Awesome, daj sobie czek na poprawną odpowiedź. –

+1

@Druid Mam tutaj to samo pytanie oprócz umieszczenia powyższego kodu w zdarzeniu Oninit strony bazowej .. czy muszę ustawić viewstateuserkey na dowolnej stronie podrzędnej. Czy mógłbyś mi powiedzieć ... –

+0

@pratapk Jak dotąd jak pamiętam, nie ma potrzeby ustawiania go na każdej stronie. – Druid

10

Rozglądałem się wokół całkiem sporo, aby znaleźć ostateczne przyczyny problemu. Ten wpis od firmy Microsoft naprawdę pomógł wyjaśnić wszystkie różne przyczyny. http://support.microsoft.com/kb/2915218 Przyczyna 4 jest co wylądowaliśmy na którym jest nieważny ViewStateUserKeyValue

Ustawianie ViewStateUserKey do Session.SessionID lub User.Identity.Name nie pracują dla nas.

Mamy przerwami dostał błąd sprawdzania poprawności z powodu następującego. Po zresetowaniu puli aplikacji przez IIS sesja zostaje odnowiona, powodując błąd. Usuwamy sesję podczas logowania, aby uniknąć utrwalania sesji, a także spowodować błąd podczas logowania.

Co ostatecznie pracował dla nas było rozwiązanie oparte cookie, które są obecnie dostępne w 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

Mógłbyś, proszę, opracować więcej? Nie tylko * linki *. – Kamiccolo

+4

Wyjaśniono, dlaczego inne rozwiązania nie działają dla nas. I wstaw próbkę kodu do postu. – Vincejtl

+0

Obecnie próbuję Twojego rozwiązania i jak na razie wygląda na to, że dobrze się spisuje. – AFract

1

bardzo dziwne, ja też miałem podobny problem na 3 dni, a teraz postanowiłem go. 1. Miałem włączone uwierzytelnianie formularzy i miał ssl fałszywe

<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" /> 
  1. ale moim httpcookies tagu miałem requiressl = true. Ponieważ w Site.Master.cs używa cookies, aby ustawić ViewStateUserKey, że miał problemy

  2. stąd byłem coraz błąd.

  3. Zmodyfikowałem to na false i uruchomiłem ponownie aplikację internetową, teraz wszystko dobrze.

Powiązane problemy