AntiForgeryToken недействителен после входа в систему

У меня есть форма, которую пользователь может опубликовать без входа в систему. Если, однако, его адрес электронной почты распознается, требуется пароль. Форма пароля проверяется через Ajax, и в случае успеха отправляется основная форма. Обе формы требуют действующего AntiForgeryToken.

Загвоздка в том, что проверка пароля как побочный продукт также выполняет вход пользователя в систему (требование клиента). Это делает токен недействительным, и основная форма не может быть отправлена.

Я попытался программно сгенерировать новый токен, но не могу заставить его работать.

Есть идеи, как решить эту проблему?

Окончательное решение

Я обнаружил, что этот вопрос полезен при вводе отражения. Однако, и это основная причина, по которой при нормальных обстоятельствах вы избегаете взлома внутренних типов, является то, что типы передвигаются между сборками и между выпусками. Как предлагает Бетти, используйте 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,
    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, null, serializer, new object[] { text });

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

string newToken = Convert.ToString(serializerType.InvokeMember(
    "Serialize",
    BindingFlags.InvokeMethod,
    null,
    serializer,
    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,
        //    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", BindingFlags.InvokeMethod, null,
                                                                 serializer, new object[] { text });

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

            newToken = Convert.ToString(serializerType.InvokeMember(
                "Serialize",
                BindingFlags.InvokeMethod,
                null,
                serializer,
                new[] { antiForgeryToken }));
        }

13
задан Community 23 May 2017 в 12:14
поделиться