I am trying to implement AntiForgeryToken for my MVC3 Application. I am having a problem with AntiForgeryToken after setting FormAuthentication cookie. Here is a simple example which explains my problem.
I have home controller with following action methods:
public class HomeController : Controller
{
public ActionResult Logon()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Logon(string userName, string password)
{
FormsAuthentication.SetAuthCookie(userName, false);
return View("About");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult About(FormCollection form)
{
return View("PageA");
}
}
And here is my Logon and About views:
Logon.cshtml:
@using (Html.BeginForm("Logon", "Home"))
{
@Html.AntiForgeryToken()
<label> UserName :</label>
<input name = "userName" type="text"/>
<br />
<label> Password :</label>
<input name = "password" type="password"/>
<br />
<br />
<input type="submit" value="LogOn" />
}
About.cshtml
@using (Html.BeginForm("About", "Home"))
{
@Html.AntiForgeryToken()
<p> This is conent of page About</p>
<input name = "moreInfo" type="text"/>
<input type="submit" value="SubmitAbout" />
}
I have no problem on “Logon” post method. It is validating the antiforgerytoken and rendering About view. Interestingly, when I do post on “About” view I am getting error “A required anti-forgery token was not supplied or was invalid”
could some one point out what I am doing wrong here?
Appreciate your help.
I did some tests, and determined that even after you call
FormsAuthentication.SetAuthCookie(...), the problem is thathttpContext.User.Identity.Namewill still be empty for the duration of the request.Therefore, to solve this issue, you need to manually set the current
Useras so:This will set the correct
Userthat is used whenHtml.AntiForgeryToken()is called.Please note that this code isn’t necessary for normal PRG-pattern websites, because after the redirect, the correct
Userwill be loaded.Also, since your
Logonmethod requires a valid user name and password, it isn’t really susceptible to CSRF attacks, so you probably don’t need to useValidateAntiForgeryTokenon that method. Maybe that’s why the AntiForgeryToken is dependent on the user name. CSRF attacks usually only exploit already-authenticated users.