AntiForgeryToken 登录后无效

2024-02-05

我有一个用户可以在不登录的情况下发布的表格。但是,如果他的电子邮件被识别,则需要密码。密码表单通过 Ajax 进行验证,如果成功,则提交主表单。两种形式都需要有效的 AntiForgeryToken。

问题是,密码检查作为副产品还会使用户登录(客户端的要求)。这会验证令牌,并且无法发送主表单。

我尝试过以编程方式生成新令牌,但无法使其工作。

关于如何解决这个问题有什么想法吗?

最终解决方案

I found this https://stackoverflow.com/questions/1347728/using-an-mvc-htmlhelper-from-a-webform问题有助于形成反思。然而,这就是在正常情况下避免破解内部类型的主要原因,因为这些类型在版本之间的程序集之间进行了很多处理。正如 Betty 建议的那样,使用 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);

升级网页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 }));
        }

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

您应该能够在回发时提取表单令牌,就像 Phil Haack 在这个帖子 http://haacked.com/archive/2011/10/10/preventing-csrf-with-ajax.aspx.

然后使用 AntiForgeryDataSerializer 类反序列化令牌,更新当前用户,再次序列化并在检查之前将其放回表单中。或者完全使用您自己的属性替换 validate 方法。

或者,您可以尝试使用密码 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 是内部类,因此您必须使用一些基本的反射来调用它们的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AntiForgeryToken 登录后无效 的相关文章

随机推荐

  • display:none 和 *ngIf = 'false' 之间有什么区别?

    The display none是CSS表 它将从 DOM 树中删除元素 这ngIf false 还从 DOM 树中删除元素 他们之间有什么区别 display none https developer mozilla org en US
  • 为什么 GCJ 找不到我导入的包中的类?

    我想将一个小型 Java 应用程序编译为 Windows 可执行文件 该应用程序非常小 只有一个主类 但它使用 Apache POI 当我编译它时 只要我将 POI Jar 放入类路径参数中 一切都会正常 但是当涉及到链接时 GCJ 无法解
  • ModelState.AddModelError - 未显示错误

    我想在控制器捕获异常后为电子邮件字段设置错误消息 catch EmailAlreadyExistsException emailAlreadyExistsException ModelState AddModelError Useracco
  • 使用 NSDateFormatter 生成 NSDate 产生 nil NSDate 值

    我正在尝试使用以下字符串生成日期 NSDateFormatter dateFormatter NSDateFormatter alloc init dateFormatter setDateFormat MMMM dd yyyy HH mm
  • Twitter bootstrap 缩略图在除 Chrome + Windows XP 之外的任何地方都无法正确对齐

    好的 我正在制作一个工作网站原型 但在使用缩略图作为 Twitter Bootstrap 的一部分时遇到了一个小障碍 我的问题很容易看出 并且适用于我测试过的每个浏览器but Chrome 20 0 1132 57 Official Bui
  • 定时器无法连接到pyqt5中的插槽

    我无法将计时器连接到 move 插槽timer timeout connect self move 这不起作用 但QtCore QTimer singleShot 50 self move 这只是一步 仅此而已 class Bullet Q
  • Symfony2:具有空值的实体表单字段

    我有一个表单定义 它使用迄今为止很棒的字段类型entity 随着选项query builder我选择我的值并显示它们 可悲的是 我需要展示一个null默认值 例如all 这是一个过滤器形式 我不喜欢choices的选项entity因为我有数
  • 以“会计”格式处理负数

    我有数据集 其负值用括号括起来 即 10 10 它是csv格式的 我该如何处理它以便R能够解释 10 as 10 谢谢 更新 我知道我可以通过替换来解决 as 消除 并使用as numeric之后 但是有没有更优雅的方法来解决这个问题 如果
  • 在 Txt 文件中查找字符串,删除整行

    我目前正在使用 node js 创建一个 IRC 机器人 该机器人允许用户将歌曲链接添加到数据库中 每次有人提交一首歌曲时 它都会添加到 shuffle txt 的新行中 如下所示 user1 The Beatles Yesterday y
  • expoClientID 去了哪里?

    我正在将 Facebook 登录添加到我的博览会应用程序中 它在文档 https docs expo dev guides authentication facebook进入我的expoClientId某处 问题是我不知道该把它放在哪里 我
  • 如何在 PHP 中绑定 SQL 变量?

    我想绑定变量而不是仅仅构建 SQL 字符串 无论如何要在 Php 中执行此操作吗 MySQL 或 PostgreSQL 的答案都会有帮助 Thanks 有例如PDO http docs php net pdo pdo 和准备好的语句 包括绑
  • 从布局 xml 文件旋转 ImageView 源

    我的布局中有这个 ImageView
  • Android 上的 flash.sensors.Accelerometer 在网络浏览器中

    加速度计UPDATE事件永远不会触发 但是isSupported当 Flash 应用程序在 Android Web 浏览器中运行时 返回 true 我怎样才能让它发挥作用 this accelerometer new Acceleromet
  • php/mysql 将行添加在一起以获得总计

    这是场景 我正在生成一份关于在特定时间段内需要缴纳会费的所有会员的报告 我成功选择每个数据库条目并将其显示为 html 表中的一行 问题是报告必须具有的总字段数 每个成员根据他们使用的服务支付不同的金额 因此我必须单独添加每个字段中的值以确
  • 服务器启动时的调用方法[重复]

    这个问题在这里已经有答案了 我试图在我的网络应用程序启动时调用一个方法 目的是启动一个计时器 以定义的时间间隔执行一些工作 当我的 jboss 7 1 Web 应用程序启动时 如何调用函数 helloworld 如果您想在 Web 应用程序
  • 如何使用 sqlalchemy-migrate 将列类型从字符变化更改为整数

    我正在使用 sqlalchemy migrate 来更改 Postgre SQL 数据库中表中的一列的类型 我使用的升级脚本是 cofing utf 8 from sqlalchemy import MetaData Table Colum
  • 如何将元标记设置为 部分中的第一个标记?

    我正在使用 JSF2 GlassFish 3 1 PrimeFaces 2 x 我在 IE9 上遇到奇怪的渲染问题 我应该能够通过插入以下内容来强制 IE9 呈现为 IE9 但问题是 它不起作用 因为 我被告知 元标记必须是该部分中的第一个
  • C# 中的堆栈溢出

    我有这个寄存器来注册我需要的所有对象 public static class ObjectRegister public static List
  • 在 WCF 服务库项目中使用自定义 ServiceHostFactory

    我正在编写一个 WCF 服务 该服务在内部严重依赖于控制反转 我想在自定义 ServiceHostFactory 内引导 初始化我的 IoC 容器 我读过一些可用的不同钩子的示例 但它们似乎都不适合我 This approach http
  • AntiForgeryToken 登录后无效

    我有一个用户可以在不登录的情况下发布的表格 但是 如果他的电子邮件被识别 则需要密码 密码表单通过 Ajax 进行验证 如果成功 则提交主表单 两种形式都需要有效的 AntiForgeryToken 问题是 密码检查作为副产品还会使用户登录