我一直在浏览开发项目的错误日志,发现以下错误(更改名称以保护有罪的无辜者) -
提供的防伪令牌适用于用户"",但当前用户为"admin".
这不是一个特别难以复制的问题 -
堆栈跟踪是 -
System.Web.Mvc.HttpAntiForgeryException(0x80004005):提供的防伪令牌适用于用户"",但当前用户为"admin".在System.Web.Helpers.AntiForgery的System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext,IIdentity identity,AntiForgeryToken sessionToken,AntiForgeryToken fieldToken)中的System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext).在System.Web.Mvc.Mvc.Asvoke.Av响应(SystemContext控件),System.Web.Mvc.AsvokeAuthorizationFilters(ControllerContext controllerContext,IList`1过滤器,ActionDescriptor actionDescriptor)的System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext)中验证(),System.Web.Mvc.Async.AsyncControllerActionInvoker. <> c__DisplayClass25.
登录方法签名是 -
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
...
}
Run Code Online (Sandbox Code Playgroud)
这与互联网"ASP.NET MVC 4 Web应用程序"模板化项目中的方法签名完全相同,这表明Microsoft认为ValidateAntiForgeryToken是必要/最佳实践,或者只是在此处添加了属性,因为它已被使用在其他地方.
显然,我无法在此方法中处理问题,因为它没有到达,ValidateAntiForgeryToken是一个预请求过滤器,它在阻止请求到达控制器之前.
在提交表单之前,我可以检查用户是否通过Ajax进行了身份验证,如果是,则尝试重定向到这些用户,或者只是删除该属性.
问题是这个 - 我理解该令牌的设计是为了防止来自另一个站点(CSRF)的请求,当用户已经针对您的站点进行了身份验证时,所以基于这个问题将它从表单中删除是一个问题,根据定义将使用它未经验证的用户?
据推测,此实例中的属性旨在缓解为您的应用程序提供虚假登录表单的恶意行为者(尽管在抛出异常时可能已经输入了他或她已经记录的详细信息 - 但它可能会提醒他们某些事情是错的).否则,从外部站点向表单提交不正确的凭据将导致与站点本身完全相同的结果?我不依靠客户验证/卫生来清理可能不安全的输入.
让其他开发人员遇到此问题(或者我们是否拥有异常富有创意的用户)如果是这样,您如何解决/减轻它?
更新:此问题在MVC5中仍然存在,完全是故意的,现在出现错误消息"提供的防伪令牌是针对与当前用户不同的基于声明的用户".使用默认模板和身份提供程序时.Microsoft Developer Evangelist和Troy的同事PluralSight作者Adam Tuliper在登录页面上的Anti forgery 令牌中提出了一个相关的问题和有趣的答案,建议只需删除令牌.
我有一个表格:
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()...
Run Code Online (Sandbox Code Playgroud)
和行动:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl, string City)
{
}
Run Code Online (Sandbox Code Playgroud)
偶尔(每周一次),我收到错误:
防伪令牌无法解密.如果此应用程序由Web场或群集托管,请确保所有计算机都运行相同版本的ASP.NET网页,并且配置指定显式加密和验证密钥.AutoGenerate不能在群集中使用.
我尝试添加到webconfig:
<machineKey validationKey="AutoGenerate,IsolateApps"
decryptionKey="AutoGenerate,IsolateApps" />
Run Code Online (Sandbox Code Playgroud)
但错误仍然偶尔出现
我注意到发生了这个错误,例如当一个人来自一台计算机然后再尝试另一台计算机时
或者有时一个自动值设置不正确的数据类型,如bool到任何jQuery代码的表单字段整数,请检查它.
发布我的ASP.NET MVC Web应用程序的新版本后,我经常看到浏览到该站点时抛出此异常:
System.Web.Mvc.HttpAntiForgeryException:未提供所需的防伪标记或无效.---> System.Web.HttpException:viewstate MAC验证失败.如果此应用程序由Web场或群集托管,请确保配置指定相同的validationKey和验证算法.AutoGenerate不能在群集中使用.---> System.Web.UI.ViewStateException:无效的viewstate.
在我的Web应用程序中访问的每个页面上都会继续发生此异常,直到我关闭Firefox.重新打开Firefox后,该网站运行良好.知道发生了什么事吗?
补充说明:
我偶尔会在正常使用期间收到此错误,并且我没有找到一种方法来阻止它而不删除需要令牌的属性,我宁愿不这样做.
我在自己的测试中遇到了这个错误(但看似随机),我从记录中知道实际登录的用户也是如此.
有没有人知道什么会导致防伪系统崩溃(除了真正的攻击),以及如何解决这个问题而不打开表格中的安全漏洞?
谢谢!
我刚刚在另一篇文章上发现了因为我的应用程序没有让用户在iisreset之后登录.
如何解决在我的ASP.Net MVC应用程序中的iisreset之后发生的AntiForgeryToken异常?
我不得不说我同意评论者这是一个人为限制.
从我读到的有关表单身份验证的内容看来,登录的会话信息全部存储在内存中,当服务器重新启动时,您将丢失该信息.
我想做的是简单地将信息存储在某个地方,最好是存储在数据库中,以便我可以继续我的会话.我似乎无法找到任何方法来扩展它来做到这一点.我错过了什么吗?我误解了它是如何工作的吗?
我意识到这是他们给我们的"免费"套件,但我宁愿不自己动手,因为有很多他们做对了,我有可能搞砸我自己的解决方案.
编辑:注意这与会话状态没有任何关系.据我所知,我根本不使用会话状态,除非框架内的某些东西在内部使用它.
我发现身份验证使用了cookie但它们还没有过期.在iisreset之后我仍然会被反弹到登录页面.