Phương pháp quan trọng là trong mã nguồn MVC: GetAntiForgeryTokenAndSetCookie
Điều này tạo ra một thể hiện của một lớp kín nội bộ gọi AntiForgeryData
.
Ví dụ được tuần tự hóa thành một cookie "__RequestVerificationToken_" + phiên bản mã hóa cơ sở 64 của đường dẫn ứng dụng.
Ví dụ tương tự của AntiForgeryData
được đăng theo thứ tự thành đầu vào bị ẩn.
Phần độc đáo của AntiForgeryData
đang có với một RNGCryptoServiceProvider.GetBytes()
Tất cả điều này có thể bị giả mạo trong một trang WebForms, bit lộn xộn chỉ là serialization của lớp kín ẩn. Thật không may là phương pháp quan trọng (GetAntiForgeryTokenAndSetCookie
) dựa trên ViewContext.HttpContext.Request
để lấy cookie, trong khi WebForm cần sử dụng HttpContext.Current.Request
thay thế.
Cập nhật
Không có nhiều thử nghiệm và rất nhiều mã, nhưng tôi nghĩ rằng tôi đã nứt này với một sự phản ánh ít. Nơi mà tôi đã sử dụng phản ánh tôi đã rời khỏi dòng tương đương nhận xét ở trên:
using System;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
/// <summary>Utility to provide MVC anti forgery tokens in WebForms pages</summary>
public class WebFormAntiForgery
{
/// <summary>Create an anti forgery token in a WebForms page</summary>
/// <returns>The HTML input and sets the cookie</returns>
public static string AntiForgeryToken()
{
string formValue = GetAntiForgeryTokenAndSetCookie();
// string fieldName = AntiForgeryData.GetAntiForgeryTokenName(null);
var mvcAssembly = typeof(HtmlHelper).Assembly;
var afdType = mvcAssembly.GetType("System.Web.Mvc.AntiForgeryData");
string fieldName = Convert.ToString(afdType.InvokeMember(
"GetAntiForgeryTokenName",
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[] { null }));
TagBuilder builder = new TagBuilder("input");
builder.Attributes["type"] = "hidden";
builder.Attributes["name"] = fieldName;
builder.Attributes["value"] = formValue;
return builder.ToString(TagRenderMode.SelfClosing);
}
static string GetAntiForgeryTokenAndSetCookie()
{
var mvcAssembly = typeof(HtmlHelper).Assembly;
var afdType = mvcAssembly.GetType("System.Web.Mvc.AntiForgeryData");
// new AntiForgeryDataSerializer();
var serializerType = mvcAssembly.GetType("System.Web.Mvc.AntiForgeryDataSerializer");
var serializerCtor = serializerType.GetConstructor(new Type[0]);
object serializer = serializerCtor.Invoke(new object[0]);
// string cookieName = AntiForgeryData.GetAntiForgeryTokenName(HttpContext.Current.Request.ApplicationPath);
string cookieName = Convert.ToString(afdType.InvokeMember(
"GetAntiForgeryTokenName",
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[] { HttpContext.Current.Request.ApplicationPath }));
// AntiForgeryData cookieToken;
object cookieToken;
HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
if (cookie != null)
{
// cookieToken = Serializer.Deserialize(cookie.Value);
cookieToken = serializerType.InvokeMember("Deserialize", BindingFlags.InvokeMethod, null, serializer, new object[] { cookie.Value });
}
else
{
// cookieToken = AntiForgeryData.NewToken();
cookieToken = afdType.InvokeMember(
"NewToken",
BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[0]);
// string cookieValue = Serializer.Serialize(cookieToken);
string cookieValue = Convert.ToString(serializerType.InvokeMember("Serialize", BindingFlags.InvokeMethod, null, serializer, new object[] { cookieToken }));
var newCookie = new HttpCookie(cookieName, cookieValue) { HttpOnly = true };
HttpContext.Current.Response.Cookies.Set(newCookie);
}
// AntiForgeryData formToken = new AntiForgeryData(cookieToken)
// {
// CreationDate = DateTime.Now,
// Salt = salt
// };
var ctor = afdType.GetConstructor(new Type[] { afdType });
object formToken = ctor.Invoke(new object[] { cookieToken });
afdType.InvokeMember("CreationDate", BindingFlags.SetProperty, null, formToken, new object[] { DateTime.Now });
afdType.InvokeMember("Salt", BindingFlags.SetProperty, null, formToken, new object[] { null });
// string formValue = Serializer.Serialize(formToken);
string formValue = Convert.ToString(serializerType.InvokeMember("Serialize", BindingFlags.InvokeMethod, null, serializer, new object[] { formToken }));
return formValue;
}
}
Việc sử dụng sau đó tương tự như MVC:
WebFormAntiForgery.AntiForgeryToken()
Nó tạo ra cùng một cookie và HTML tương tự như MVC phương pháp.
Tôi đã không làm phiền với các phương pháp miền và muối, nhưng chúng sẽ khá dễ dàng để thêm vào.
Tôi có cùng một vấn đề - một trang WebForms kế thừa cần đăng lên một hành động MVC với một 'AntiForgeryToken'. Tôi muốn thêm 'Html.AntiForgeryToken()' vào trang WebForms mà không cần viết lại nó trong MVC. – Keith