Cơ chế của ASP.NET MVC AntiForgeryToken dựa trên HttpContext.User
hiện tại. Nó sử dụng giá trị đó để tạo mã thông báo khi bạn gọi Html.AntiForgeryToken()
. Về cơ bản nó là OK (xem giải thích trong last paragraph here) nhưng một vấn đề phát sinh khi bạn đăng nhập thông qua một cuộc gọi Ajax . Trong mã của tôi, khi người dùng đăng nhập, thông tin đăng nhập được gửi dưới dạng đối tượng Json trong Ajax (giá trị trường ẩn AntiForgeryToken
ẩn cũng được gửi bên trong Json), máy chủ xác thực người dùng, áp dụng FormsAuthentication.SetAuthCookie() và trả về kết quả Json chứa một số dữ liệu người dùng cụ thể. Bằng cách đó, tôi có thể tránh làm mới toàn bộ trang khi đăng nhập.MVC3 AntiForgeryTắt vỡ khi đăng nhập Ajax
Vấn đề là mọi yêu cầu Ajax tiếp theo đối với máy chủ hiện không thành công theo số ValidateAntiForgeryTokenAttribute
, vì bây giờ nó mong đợi một mã thông báo chống giả mạo không tương thích với cookie chống giả mạo.
Làm cách nào để nhận mã thông báo chống giả mạo hợp lệ để đặt vào trường ẩn của khách hàng để mọi yêu cầu Json sau khi đăng nhập thành công?
Tôi cố gắng lấy mã thông báo trường ẩn mới theo cách thủ công (sử dụng AntiForgery.GetHtml()
trên hành động, giải nén chuỗi mã thông báo, trả lại cho khách hàng trong Json và đặt nó vào trường ẩn chống giả theo cách thủ công trong JavaScript) nhưng nó không hoạt động - một cuộc gọi Ajax tiếp theo thất bại trên ValidateAntiForgeryTokenAttribute
trên máy chủ. Thực tế, mọi cuộc gọi đến AntiForgery.GetHtml()
(mà về cơ bản là những gì mà người trợ giúp Html.AntiForgeryToken()
làm) tạo ra một mã thông báo khác, làm mất hiệu lực mã thông báo trước đó.
Tôi cũng đã cố gắng đặt HttpContext.User = new GenericPrincipal(new GenericIdentity(email), null);
là chi tiết here nhưng không hoạt động.
Lưu ý:This solution không làm việc cho tôi, vì tình hình cụ thể của tôi: Một Ajax đăng nhập làm thay đổi nhận dạng người dùng trên máy chủ và vì thế mỗi thẻ được tạo ra trước khi đăng nhập không hợp lệ; this solution cũng không áp dụng bởi vì nó giải quyết một vấn đề khác.
Tại sao bạn sử dụng AntiForgeryToken trên trang đăng nhập của mình khi người dùng chưa được xác thực. Bạn đang bảo vệ cái gì? –
Tính năng đăng nhập không phải là một trang, nó là một mảnh bên trong mẫu của trang. Nó thực sự không cần thiết trong tính năng đăng nhập, nhưng vấn đề phát sinh sau đó - sau khi phương thức đăng nhập ở phía máy chủ đặt người dùng hiện tại (HttpContext.User) và trả về. Ở giai đoạn này, trang đã có một số trường mã thông báo chống giả mạo ẩn, để phục vụ các cuộc gọi Ajax tiếp theo. –
Phil Haack đăng bài viết này cách đây vài ngày. Đây có phải là cách liên quan đến vấn đề của bạn không? http://haacked.com/archive/2011/10/10/preventing-csrf-with-ajax.aspx ... "Vấn đề nằm ở thực tế là dưới mui xe, sâu bên trong ngăn xếp cuộc gọi, thuộc tính nhìn trộm vào bộ sưu tập Request.Form để lấy mã thông báo chống giả mạo. Nhưng khi bạn đăng dữ liệu được mã hóa JSON, không có bộ sưu tập biểu mẫu nào để nói đến. " – JasperLamarCrabb