问题
I've recently put Live a web application which was built using MVC 4 and Entity Framework 5. The MVC application uses Razor Views.
I noticed using Elmah that when users are logging into the application, sometimes they are getting the following error
The provided anti-forgery token was meant for user "" but the current user is "user"
I've done a bit of research already on how to fix this issue, but nothing seems to work for me. Please see my Login View and corresponding Controller Actions below.
Razor View
@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>
}
}
Controller
[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
}
}
I thought this all looked OK, but still the error persists. Does any have any ideas on how to fix this problem?
Your help is greatly appreciated.
Thanks.
回答1:
I believe this is occurring because the users are double-clicking the submit button on the form. At least that's EXACTLY the case on my site.
Troubleshooting anti-forgery token problems
回答2:
The validation code that runs against an AntiForgeryToken also checks your logged in user credentials haven’t changed – these are also encrypted in the cookie. This means that if you logged in or out in a popup or another browser tab, your form submission will fail with the following exception:
System.Web.Mvc.HttpAntiForgeryException (0x80004005):
The provided anti-forgery token was meant for user "", but the current user is "SomeOne".
You can turn this off by putting AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
in Application_Start
method inside Global.asax
file.
When a AntiForgeryToken doesn’t validate your website will throw an Exception of type System.Web.Mvc.HttpAntiForgeryException
. You can make this a little easier by at least giving the user a more informative page targeted at these exceptions by catching the 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);
}
}
More info:
Anti forgery token is meant for user “” but the current user is “username”
Html.AntiForgeryToken – Balancing Security with Usability
回答3:
I had the same problem when
- User logs in
- Then on the Home Page the User hits Back Button to go back to Login
- User logs in as a different User
- This gave the exception : The provided anti-forgery token was meant for user "" but the current user is "user"
I found this was happening only in IE and I fixed it by doing a couple of things
- Disabled output caching for the login page, because in debug mode I found that hitting the back button did not generate a new request to the Login page
On the login page I added a check to see if the user is already authenticated, and if so logged out the user, and then redirected to the Login page again.
[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(); }
来源:https://stackoverflow.com/questions/20326990/mvc-4-provided-anti-forgery-token-was-meant-for-user-but-the-current-user-is