AntiForgeryToken inválido após o login
Tenho um formulário que o usuário possa postar sem fazer login. Se, no entanto, seu e-mail for reconhecido, será necessária uma senha. O formulário da senha é validado pelo Ajax e, se for bem-sucedido, o formulário principal será enviado. Ambos os formulários requerem um AntiForgeryToken válido.
O problema é que a verificação da senha como um biproduto também faz login no usuário (um requisito do cliente). Isso invalida o token e o formulário principal não pode ser enviad
Tentei gerar programaticamente um novo token, mas não consigo fazê-lo funciona
Alguma ideia de como resolver isso
Solução fina
Eu encontreiest pergunta para ser útil na digitação da reflexão. No entanto, e esse é o principal motivo pelo qual, em circunstâncias normais, você evitaria invadir tipos internos, é que os tipos são manipulados entre os assemblies, muito entre os releases. Como Betty sugere, use o ILSpy para encontrar coisa
Este é o código final.
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);
Upgrade para páginas da Web 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 }));
}