N次登录尝试失败后如何显示验证码?

时间:2014-12-25 10:30:59

标签: asp.net-mvc security captcha asp.net-identity-2

我有一个ASP.NET MVC 5应用程序,它使用ASP.NET Identity 2.0进行用户身份验证。

目前,用户在每次登录尝试时都被迫输入验证码,但它会导致许多关于身份验证复杂性的抱怨。

主要目标是让人类尽可能简单地登录,并使机器人尽可能复杂。

我决定在一定数量的失败登录尝试后显示验证码。关于它有many already asked questions,但我找不到能够帮助我构建完整解决方案的答案。 我发现这个question关于跟踪失败的尝试,但它也使用了锁定,这不是我想要的。根据{{​​3}},回答部分所需的功能在旧的ASP.NET成员资格提供程序中可用,并且在ASP.NET身份中不可用(但是?)。

所以,我最终得到了以下简化算法:

  1. 如果提供的登录名和密码对正确,则登录用户。
  2. 如果登录名或密码不正确,则记录登录尝试失败。
  3. 如果记录了三次用户登录尝试失败,则显示带验证码的登录页面。
  4. 如果输入的验证码有效,则刷新失败的登录尝试次数,然后转到1.
  5. 如果输入的验证码无效,则再次显示带验证码的登录页面。
  6. 问题是:如何将传入请求区分为特定登录请求?

    我无法依赖Cookie,会话,IP等,因为任何机器人都可以更改它们。我也不能依赖登录,因为登录可能不完全存在。显而易见的方法是创建一个单独的表来存储登录,失败的尝试次数和时间戳,但机器人可以使用假登录轻松地使用伪登录,尽管我可以通过删除一个schedlued作业中的旧条目来解决这个问题。

    这是有效的解决方案吗?有没有更好的方法呢?

1 个答案:

答案 0 :(得分:4)

身份框架具有每个用户登录失败的计数。您可以通过await UserManager.AccessFailedAsync(userId)增加它。属性ApplicationUser.AccessFailedCount存储用户记录的失败计数。并重置失败的计数调用await UserManager.ResetAccessFailedCountAsync(userId)
所以这可以利用。

但是,这不计入无效的用户名 - 数据库中不存在用户的登录尝试。对于这种情况,您可以使用您的建议表通过cron-task清除常规记录。

但是如果用户尝试登录并在每次尝试时放置不同的用户名,则此方法将失败。所以无论如何我都会在那里扔一块饼干,但不要太依赖它,因为它知道它很容易被杀死。

另一种解决方案是在每个页面上使用新的Google reCaptcha。然而,这是一项新技术,there are reports并不完全可靠。