我最近发布了一个使用MVC 4和实体框架5构建的web应用程序。MVC应用程序使用Razor视图。
我在使用Elmah时注意到,当用户登录应用程序时,有时会收到以下错误
The provided anti-forgery token was meant for user "" but the current user is "user"
我已经就如何解决这个问题做了一些研究,但似乎没有什么对我有效。请参阅下面的登录视图和相应的Controller Actions。
剃刀视图
@if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div class="formEl_a">
<fieldset>
<legend>Login Information</legend>
<div class="lbl_a">
Email
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.Email, new { @class = "inpt_a" })<br />
@Html.ValidationMessageFor(m => m.Email)
</div>
<div class="lbl_a">
@Html.LabelFor(m => m.Password)
</div>
<div class="editor-field sepH_b">
@Html.PasswordFor(m => m.Password, new { @class = "inpt_a" })<br />
@Html.ValidationMessageFor(m => m.Password)
</div>
</fieldset>
</div>
<br />
<p>
<input type="submit" value="Log In" class="btn btn_d sepV_a" />
</p>
}
}
控制器
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && _accountService.Logon(model.Email, model.Password, true))
{
//Validate
}
else
{
// inform of failed login
}
}
我以为这一切看起来都还可以,但错误仍然存在。有人对如何解决这个问题有什么想法吗?
非常感谢你的帮助。
谢谢。
我相信这是因为用户双击了表单上的提交按钮。至少我的网站上确实是这样。
解决防伪令牌问题
针对AntiForgeryToken运行的验证代码还会检查您登录的用户凭据是否已更改–这些凭据也在cookie中加密。这意味着,如果您在弹出窗口或其他浏览器选项卡中登录或注销,您的表单提交将失败,出现以下异常:
System.Web.Mvc.HttpAntiForgeryException (0x80004005):
The provided anti-forgery token was meant for user "", but the current user is "SomeOne".
您可以通过将AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
放在Global.asax
文件中的Application_Start
方法中来关闭此功能。
当AntiForgeryToken未验证时,您的网站将抛出类型为System.Web.Mvc.HttpAntiForgeryException
的异常。您可以通过捕捉HttpAntiForgeryException,至少为用户提供一个针对这些异常的信息更丰富的页面,从而使这一点变得更容易。
private void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex is HttpAntiForgeryException)
{
Response.Clear();
Server.ClearError(); //make sure you log the exception first
Response.Redirect("/error/antiforgery", true);
}
}
更多信息:
防伪令牌适用于用户",但当前用户是"用户名"
Html.AntiForgeryToken–平衡安全性和可用性
时我也遇到了同样的问题
- 用户登录
- 然后在主页上,用户点击返回按钮返回登录
- 用户以其他用户身份登录
- 这给出了异常:提供的防伪令牌是为用户"提供的,但当前用户是"user"
我发现这种情况只发生在IE中,我通过做一些来解决它
- 禁用了登录页面的输出缓存,因为在调试模式下,我发现点击后退按钮不会生成对登录页面的新请求
-
在登录页面上,我添加了一个检查,查看用户是否已经通过身份验证,如果已经,则注销用户,然后再次重定向到登录页面。
[AllowAnonymous] [OutputCache(NoStore=true, Location=System.Web.UI.OutputCacheLocation.None)] public ActionResult Login) { if (HttpContext.Request.IsAuthenticated) { WebSecurity.Logout(); Session.Abandon(); return RedirectToAction("Login"); } return View(); }