asp.net-mvc – AntiForgeryToken登录后无效

前端之家收集整理的这篇文章主要介绍了asp.net-mvc – AntiForgeryToken登录后无效前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一张表格,用户可以在没有登录的情况下发布.但是,如果他的电子邮件被识别,则需要密码.密码表格通过Ajax进行验证,如果成功提交主表单.两种形式都需要有效的AntiForgeryToken.

捕获是,作为双产品的密码检查也会对用户进行签名(来自客户端的要求).这使令牌无效,主表单无法发送.

我已经以编程方式生成了一个新的令牌,但是我无法让它工作.

关于如何解决这个问题的任何想法?

最终解决方

我发现this的问题有助于打造反思.然而,这正是在正常情况下,您将避免黑客内部类型的主要原因,这些类型是在版本之间的程序集之间进行的.贝蒂建议,使用ILSpy来查找东西.

这是最终的代码.

if (signIn)
    FormsAuth.SignIn(user.Email,false);


var mvcAssembly = typeof(AntiForgery).Assembly;
var afdType = mvcAssembly.GetType("System.Web.Helpers.AntiForgeryData");
string fieldName = Convert.ToString(afdType.InvokeMember(
    "GetAntiForgeryTokenName",BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod,null,new object[] { null }));

var serializerType = mvcAssembly.GetType("System.Web.Helpers.AntiForgeryDataSerializer");
var serializerCtor = serializerType.GetConstructor(new Type[0]);
object serializer = serializerCtor.Invoke(new object[0]);


string text = HttpContext.Request.Form[fieldName];
object antiForgeryData = serializerType.InvokeMember("Deserialize",BindingFlags.InvokeMethod,serializer,new object[] { text });

afdType.GetProperty("Username").SetValue(antiForgeryData,signIn ? user.Email : string.Empty,null);

string newToken = Convert.ToString(serializerType.InvokeMember(
    "Serialize",new object[] { antiForgeryData }));

return Content(JsonConvert.SerializeObject(new
                                                {
                                                    success = true,newAntiForgeryToken = newToken
                                                }),Constant.JsonContentType);

升级为WebPages 2.0

var mvcAssembly = typeof(AntiForgery).Assembly;
        var afdType = mvcAssembly.GetType("System.Web.Helpers.AntiXsrf.AntiForgeryToken");
        //string fieldName = Convert.ToString(afdType.InvokeMember(
        //    "GetAntiForgeryTokenName",//    BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod,//    null,//    new object[] { null }));

        string fieldName = "__RequestVerificationToken";

        var serializerType = mvcAssembly.GetType("System.Web.Helpers.AntiXsrf.AntiForgeryTokenSerializer");
        var serializerCtor = serializerType.GetConstructor(new Type[0]);
        object serializer = serializerCtor.Invoke(new object[0]);


        string text = HttpContext.Request.Form[fieldName];
        string newToken = String.Empty;

        if (!String.IsNullOrEmpty(text))
        {
            object antiForgeryToken = serializerType.InvokeMember("Deserialize",new object[] { text });

            afdType.GetProperty("Username").SetValue(antiForgeryToken,null);

            newToken = Convert.ToString(serializerType.InvokeMember(
                "Serialize",new[] { antiForgeryToken }));
        }
@H_403_20@

解决方法

当前用户以表单数据存储在防伪令牌中,并与回覆时的当前用户进行比较.

您应该能够以与Phil Haack在this post中相同的方式在回发时拉出表单令牌.

然后使用AntiForgeryDataSerializer类对令牌进行反序列化,更新当前用户,将其重新序列化,并在检查之前将其放回表单中.或者使用您自己的属性来完全替换验证方法.

或者,而不是在主窗体回发上更新它,您可以尝试使用密码ajax请求发送更新的令牌并更新表单.无论哪种方式,基本方法是一样的,反序列化,更新用户,序列化,替换令牌.

string antiForgeryTokenName = AntiForgeryData.GetAntiForgeryTokenName(null);
string text = context.Request.Form[antiForgeryTokenName];
AntiForgeryDataSerializer serializer = new AntiForgeryDataSerializer();

AntiForgeryData antiForgeryData = serializer.Deserialize(text); 
antiForgeryData.Username = AntiForgeryData.GetUsername(context.User);
string newToken = serializer.Serialize(antiForgeryData);

AntiForgeryDataSerializer和AntiForgeryData是内部类,所以你必须使用一些基本的反射来调用它们的方法.

@H_403_20@ @H_403_20@ 原文链接:https://www.f2er.com/aspnet/250110.html

猜你在找的asp.Net相关文章