登录请求验证令牌问题 [英] Login request validation token issue

查看:497
本文介绍了登录请求验证令牌问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在经历一个开发项目的错误日志,发现如下错误(更名为保护<击>犯无辜的) -

I have been going through the error logs of a development project and found the following error (name changed to protect the guilty innocent)-

所提供的防伪标记是为了用户,但目前
  用户是admin。

The provided anti-forgery token was meant for user "", but the current user is "admin".

这是不是一个特别棘手的问题重现 -

This was not an especially difficult issue to reproduce-


  1. 在登录页面打开应用

  2. 在登录前打开同一个浏览器同一台计算机,即可在登录页面上第二个窗口或标签

  3. 登录在第一个窗口(或者实际上秒,顺序无所谓)

  4. 尝试在余下的登录窗口登录

  1. Open the application at the login page
  2. Open a second window or tab in the same browser on the same computer to the login page before logging in
  3. Login in the first window (or indeed second, the order doesn't matter)
  4. Attempt to login in the remaining login window

堆栈跟踪为 -

System.Web.Mvc.HttpAntiForgeryException(0X80004005):提供的
  防伪标记是为了用户,但目前用户
  管理员。在
  System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase
  HttpContext的,身份的IIdentity,AntiForgeryToken sessionToken,
  AntiForgeryToken fieldToken)在
  System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase
  HttpContext的)在System.Web.Helpers.AntiForgery.Validate()在
  System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext
  filterContext)在
  System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext
  controllerContext,IList`1过滤器,ActionDescriptor actionDescriptor)
  在
  System.Web.Mvc.Async.AsyncControllerActionInvoker&LT;> C_的 DisplayClass25.b 的_1e(的AsyncCallback
  AsyncCallback的,对象asyncState)

System.Web.Mvc.HttpAntiForgeryException (0x80004005): The provided anti-forgery token was meant for user "", but the current user is "admin". at System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken) at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext) at System.Web.Helpers.AntiForgery.Validate() at System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext) at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_DisplayClass25.b_1e(AsyncCallback asyncCallback, Object asyncState)

登录方法签名 -

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
...
}

这是完全一样的签名在网上ASP.NET MVC 4 Web应用程序的方法模板项目,这表明微软要么觉得ValidateAntiForgeryToken是必要的/最佳实践,或者干脆在这里,因为添加的属性它被用于其他地方。

This is exactly the same as the signature for the method in a internet "ASP.NET MVC 4 Web Application" templated project, which indicates that Microsoft either felt the ValidateAntiForgeryToken was necessary/best practice, or simply added the attribute here because it was used everywhere else.

显然有什么我可以做,以处理这个问题的的这种方法没有达到它的ValidateAntiForgeryToken是pre-请求,过滤器,它是前阻挡请求到达控制器。

Obviously there is nothing I can do to handle the problem within this method as it isn't reached, the ValidateAntiForgeryToken is a pre-request filter and it is blocking the request before it reaches the controller.

我可以检查用户是否通过Ajax验证提交表单之前并尝试如果是重定向到他们,或者干脆删除属性。

I could check if the user is authenticated via Ajax before submitting the form and attempt to redirect to them if so, or simply remove the attribute.

问题是这样的 - 我明白令牌设计,以prevent请求从其他网站(CSRF),当用户的已验证对您的网站的,这样基础上的这是一个问题,从该定义将被未授权的​​用户使用的形式将其删除

The question is this - I understand that the token is design to prevent requests from another site (CSRF) when the user is already authenticated against your site so on that basis is it an issue to remove it from a form which by definition will be used by unauthenticated users?

presumably在这种情况下该属性的目的是减少恶意行为者为您的应用提供虚假的登录表单(虽然由当时的抛出异常presumably用户已经进入他或她的详细信息,这将有被记录 - 但它可能会提醒他们什么是错的)。否则提交不正确的凭据的形式从外部站点将产生完全相同的结果作为网站本身肯定吗?我不依赖于客户端验证/卫生清理潜在的不安全输入。

Presumably the attribute in this instance is designed to mitigate malicious actors providing fake login forms for your application (although by the time the exception is thrown presumably the user has already entered his or her details which will have been recorded - but it might alert them something is wrong). Otherwise submitting incorrect credentials to the form from an external site will result in exactly the same result as on the site itself surely? I am not relying on client validation/sanitation to clean up potentially unsafe input.

有其他开发者遇到过这个问题(或者我们有不同寻常的创意用户),如果是你怎么样解决/减轻呢?

Have other devs come across this issue (or do we have unusually creative users) and if so how have you resolved/mitigated it?

更新:提供的防伪标记是为那些比当前用户不同的基于声明的用户这个问题仍然存在MVC5,完全故意,现在用错误信息使用默认的模板和身份提供商时。有一个从微软开发传播者和特洛伊的同胞PluralSight作者亚当Tuliper一个相关的问题和有趣的答案在在登录页面其中建议简单地删除令牌反伪造令牌。

Update: This issue still exists in MVC5, entirely intentionally, now with the error message "The provided anti-forgery token was meant for a different claims-based user than the current user." when using default template and Identity providers. There is a relevant question and interesting answer from Microsoft Developer Evangelist and Troy's fellow PluralSight author Adam Tuliper at Anti forgery token on login page which recommends simply removing the token.

推荐答案

我刚刚测试过这种模式在 ASafaWeb 同样的结果(这使用相同的默认实现)。这就是我认为正在发生的事情。

I've just tested this pattern on ASafaWeb with the same result (it uses the same default implementation). Here's what I believe is happening


  1. 这两种登录表单负载相同__RequestVerificationToken的cookie(它只是在同一个DOM同样一组)和相同的__RequestVerificationToken隐藏字段。这些记号键控匿名用户。

  2. 登录形式与上述令牌的帖子,验证然后将它们返回一个权威性的cookie现在是在浏览器的DOM

  3. 登录B型岗位的上述令牌,但现在它也与登录表单的设置,以及在auth cookie的张贴。

  1. Both login forms load with the same __RequestVerificationToken cookie (it's just the same one set in the same DOM) and the same __RequestVerificationToken hidden field. These tokens are keyed to an anonymous user.
  2. Login form A posts with the above tokens, validates them then returns an auth cookie which is now in the browser DOM
  3. Login form B posts also with the above tokens but now it's also posting with the auth cookie set from login form A as well.

的问题是,令牌在步骤3验证,因为它键合到匿名用户,但它在通过认证的用户的请求被传递。这就是为什么你看到的错误:提供的防伪标记是为了用户,而当前用户是admin

The problem is that the token isn't validating in step 3 because it's keyed to an anonymous user but it's being passed in the request by an authenticated user. This is why you're seeing the error: The provided anti-forgery token was meant for user "", but the current user is "admin"

由于B型的形式张贴的形式,因此B的期望匿名用户发布之前加载你只是有这个问题。

You're only having this issue because form B loaded before form A posted therefore form B is expecting to be posted by an anonymous user.

它是一个问题,从该定义将被未授权的​​用户使用的形式去除呢?

在predominant潜在的风险,防伪标记对保护是CSRF其中一般的利用经过验证的用户由于这样的事实,他们的浏览器可以欺骗发行的任何请求将被自动伴随着AUTH的cookie,因此动作将代表他们执行。这种风险不登录表单上存在,因为通常用户没有通过验证,这里的最坏CSRF的情况是,一个登录是伪造的,然后失败;你不完全代表了用户的转账!

The predominant underlying risk that anti-forgery tokens protect against is CSRF which usually takes advantage of authenticated users due to the fact that any requests their browser can be tricked into issuing will be automatically accompanied by an auth cookie hence the action will be performed on their behalf. This risk doesn't exist on the login form because usually the user isn't authenticated and the worst CSRF case here is that a login is forged and then fails; you're not exactly transferring money on the user's behalf!

有其他的优势,以防伪标记,但:例如,它prevents蛮力攻击实际执行的方法和击中DB。你需要决定,如果你这个少担心,更担心的是你在你的问题遇到的情况。如果不是这样,你需要的地方砸下来到请求管道,如果AUTH的cookie已经是防伪验证发生前present请求采取行动。

There are other advantages to the anti-forgery token though: for example it prevents brute force attacks actually executing the method and hitting the DB. You need to decide if you're less worried about this and more worried about the scenario you're encountering in your question. Either that or you need to drop down into the request pipeline somewhere and take action if an auth cookie is already present in the request before the anti-forgery validation occurs.

不过坦率地说,我不知道我看到的问题;重现此问题的用户可以拥有多个登录表单在同一时间打开,然后尝试登录到每个相继 - 这真的会发生足够的理由担心?而当它发生,它真正的问题是,第二次登录返回一个自定义错误页(当然你会在生产中做)?恕我直言,保持默认的行为。

Frankly though, I'm not sure I see the problem; to reproduce this issue the user has to have multiple login forms open at the same time and then try logging into each in succession - is this really going to happen enough to worry about? And when it does happen, does it really matter that the second login returns a custom error page (which of course you'd do in production)? IMHO, leave the default behaviour.

这篇关于登录请求验证令牌问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆