2009-09-13 27 views
16

Tôi đã điều sau đây trong lớp BasePage tôi mà tất cả các trang ASPX của tôi xuất phát từ:Thiết ViewStateUserKey mang lại cho tôi một "Xác nhận của ViewState MAC thất bại" lỗi

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

Tôi cũng có một bộ machineKey trong Web.config. Tôi không nghĩ lỗi này là do trang trại vì điều này cũng xảy ra trên máy tính của tôi.

Máy chủ lưu trữ của tôi hiện đã được nâng cấp lên .NET 3.5 SP1. Sau bản cập nhật này, mỗi lần tôi biên dịch với cài đặt ViewStateUserKey ở trên, tôi liên tục nhận được lỗi "Xác thực MAC của ViewState không thành công" trên mỗi lần đăng lại.

Tôi đang làm gì sai ở đây? Cài đặt này có còn cần thiết nữa với bản cập nhật khung mới nhất không?

Trả lời

14

OK - Im một năm muộn để cuộc trò chuyện - nhưng làm thế nào đây là câu trả lời đúng? Điều này chỉ áp dụng trong trường hợp người dùng được xác thực và sử dụng ViewStateUserKey vì tên người dùng dễ đoán hơn nhiều so với GUID id phiên.

BTW nếu bạn muốn 'sửa' mã lên trên, hãy sử dụng ID phiên, tuy nhiên bạn phải đặt biến phiên để id phiên ngừng thay đổi mỗi lần. Ví dụ Session["Anything"] = DateTime.Now

ViewStateUserKey = Session.SessionID; 

Điều này tất nhiên là giả sử bạn đang sử dụng phiên, nếu không bạn cần một số quan trọng khác để sử dụng như tên người dùng hoặc bất kỳ guid khác giữ trong một cookie.

+1

Một lưu ý bổ sung, đôi khi tôi thấy thay đổi sessionid mỗi lần cho đến khi phiên được sử dụng và các lần cookie phiên được gửi đến máy khách ngay lập tức mà không sử dụng phiên. Tôi không chắc chắn 100% tại sao về điều này nhưng chỉ là một cái gì đó tôi đã nhận thấy. –

+0

Điều này rất hữu ích. Tôi không biết rằng ASP không giữ phiên nếu không có gì được lưu trong nó. – Reza

3

Bạn có thể tắt mã hóa ViewState MAC bằng thuộc tính EnableViewStateMac @Page không?

+0

Vâng, nó hoạt động nếu tôi làm điều này. Tôi muốn loại bỏ các thiết lập ViewStateUserKey nếu nó không sử dụng ... – Druid

+0

Vâng, nếu loại bỏ các công trình ViewStateUserKey và bạn không cần nó ... –

+1

Đúng, nhưng có vẻ như việc cài đặt này sẽ giúp chống lại một cú nhấp chuột (CSRF)) tấn công ... – Druid

4

tôi cố định nó cho bây giờ bằng cách thay đổi mã để:

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

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

Tuyệt vời, hãy tự mình kiểm tra câu trả lời đúng. –

+1

@Druid Tôi đã có cùng một câu hỏi ở đây ngoài việc đặt mã ở trên trong sự kiện Oninit của trang cơ sở .. tôi có cần đặt viewstateuserkey trong bất kỳ trang con nào không. Bạn có thể cho tôi biết .... –

+0

@pratapk Cho đến nay như tôi nhớ, không cần phải đặt nó trên mọi trang. – Druid

10

Tôi đã tìm kiếm xung quanh một chút để tìm nguyên nhân chính xác của vấn đề. Bài đăng này từ Microsoft thực sự đã giúp giải thích tất cả các nguyên nhân khác nhau. http://support.microsoft.com/kb/2915218 Nguyên nhân 4 là những gì chúng tôi đã hạ cánh trên đó là một hợp lệ ViewStateUserKeyValue

Thiết ViewStateUserKey để Session.SessionID hoặc User.Identity.Name không làm việc cho chúng tôi.

Chúng tôi liên tục nhận được lỗi xác thực do những điều sau đây. Khi nhóm ứng dụng được đặt lại bởi IIS, phiên được gia hạn có hiệu lực gây ra lỗi. Chúng tôi thả Phiên trên đăng nhập để tránh việc định hình phiên, cũng dẫn đến lỗi khi đăng nhập.

Điều cuối cùng phù hợp với chúng tôi là giải pháp dựa trên cookie, hiện được cung cấp trong 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

Bạn có thể vui lòng, chi tiết hơn? Không chỉ * liên kết *. – Kamiccolo

+4

Giải thích lý do tại sao các giải pháp khác không hiệu quả đối với chúng tôi. Và đặt mẫu mã lên bài đăng. – Vincejtl

+0

Tôi hiện đang thử giải pháp của bạn và cho đến nay có vẻ như hoạt động tốt. – AFract

1

rất lạ, tôi cũng có vấn đề tương tự trong 3 ngày và bây giờ tôi giải quyết nó. 1. Tôi đã kích hoạt hình thức xác thực và có ssl sai

<forms defaultUrl="~/" loginUrl="~/Account/Login.aspx" requireSSL="false" timeout="2880" /> 
  1. nhưng trong thẻ của tôi httpcookies tôi đã requireSSL = true. Kể từ trong Site.Master.cs nó sử dụng cookie để thiết lập các ViewStateUserKey, nó đã có vấn đề

  2. vì thế tôi đã nhận được báo lỗi.

  3. Tôi đã sửa đổi điều này thành ứng dụng web sai và khởi động lại, giờ đây tất cả đều tốt.

Các vấn đề liên quan