【问题标题】:ASP.NET MVC - ValidateAntiForgeryToken expiringASP.NET MVC - ValidateAntiForgeryToken 过期
【发布时间】:2012-09-22 15:16:32
【问题描述】:

在网页中,我们提供了一个超链接 (GET),用户可以单击该超链接进行身份验证:

@Html.ActionLink("Please Login", "MyMethod", "MyController")

这映射到以下返回视图的控制器方法:

    [RequireHttps]
    public ActionResult MyMethod()
    {
        return this.View(new MyModel());
    }

此视图包含用户提供其凭据的表单;表单包含所需的 AntiForgeryToken。

当用户提交表单时,会调用如下Controller方法:

    [HttpPost]
    [RequireHttps]
    [ValidateAntiForgeryToken]
    public ActionResult MyMethod(MyModel model)
    {
        // my logic
    }

这很好用,大多数时候......

但是,如果用户让他们的浏览器打开“很长”一段时间,然后快速连续执行以下步骤:

  1. 单击超链接 (GET) 以加载登录表单
  2. 填写表格并提交

他们收到一个异常通知,通知他们防伪令牌未提供或无效。

我不明白为什么会这样:视图(包含表单)是在浏览器休眠后创建的,因此防伪令牌应该都是“新鲜的”。但是,这种设计显然有问题,但我不确定如何最好地纠正它。

如果您有任何建议,请提前感谢。

格里夫

【问题讨论】:

  • 我只想提一下,我的应用已经遇到这个问题几年了,我很想有一个解决方案。我尝试了所有标准的机器密钥修复。
  • 卷起袖子,潜入源头。我来操作泵。
  • 有一个article 详细说明了令牌的验证步骤。一个步骤是针对 Context 的用户进行验证 - 不确定这是否可能不合时宜。无论哪种方式,解决方案仍不清楚。

标签: asp.net-mvc asp.net-mvc-3 security csrf antiforgerytoken


【解决方案1】:

我正在处理同样的问题,虽然我理解这个问题,但我还不确定最佳解决方案。

Anti-ForgeryToken 进程将输入值放置在表单中,第二个值存储在 cookie RequestVerificationToken 中。这两个都提交给服务器,如果不匹配就会抛出错误。

RequestVerficationToken cookie 的过期值设置为 Session。因此,当用户让浏览器在页面上长时间打开然后提交时,cookie 的时间戳会与服务器上的会话超时值(默认为 20 分钟左右)进行比较,如果超过,则会将其删除因此令牌验证失败。

可能的解决方案,都有潜在的问题;

  1. 在页面上放置一个 javascript 计时器并在某个值以下刷新 比您的会话超时。
  2. 在服务器上捕获 System.Web.Mvc.HttpAntiForgeryException - 并重定向 到同一页面。
  3. 增加会话超时时间
  4. 更改防伪令牌的过期时间

【讨论】:

  • 注意,据我了解,机器密钥用于验证服务器上的 Anti-ForgeryToken,并且是在 webfarm 中使用所必需的(设置静态机器密钥可能会解决导致的错误情况通过重新启动服务器上的工作进程),但是它不会解决 cookie 过期问题。
  • 正如您所说,cookie 过期与会话相关,因此解决方案 3 也应该导致解决方案 4。除非您以某种方式手动覆盖 cookie 的生成方式。我过去曾尝试过解决方案 1,但它并不总是完全可靠,因此 3(如果可能)和 2 的组合似乎是最好的选择。
猜你喜欢
  • 1970-01-01
  • 2015-11-24
  • 2019-01-26
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
  • 2015-01-14
  • 2018-05-02
相关资源
最近更新 更多