ASP.NET MVC's AntiForgeryToken mechanism is based on the current HttpContext.User
. It uses that value to construct the token when you call Html.AntiForgeryToken()
. Basically it is OK (see an explanation in the last paragraph here) but a problem arises when you log in through an Ajax call.
In my code, when a user logs in, the credentials are sent as a Json object in Ajax (the AntiForgeryToken
hidden field value is also sent inside the Json), the server authenticates the user, applies FormsAuthentication.SetAuthCookie(), and returns a Json result which contains some user-specific data. In that way, I can avoid full page refresh upon login.
The problem is that every subsequent Ajax request to the server now fails upon ValidateAntiForgeryTokenAttribute
, because it now expects an anti-forgery token that is incompatible with the anti-forgery cookie.
How can I get a valid anti-forgery token to put in the client's hidden field so every Json request after login will succeed?
I tried to get a new hidden-field token manually (using AntiForgery.GetHtml()
on the action, extracting the token string itself, returning it to the client in Json and placing it in the anti-forgery hidden field manually in JavaScript) but it does not work - a subsequent Ajax call fails on the ValidateAntiForgeryTokenAttribute
on the server.
In fact, every call to AntiForgery.GetHtml()
(which is essentially what Html.AntiForgeryToken()
helper does) produces a different token, which invalidates the previous one.
I also tried to set HttpContext.User = new GenericPrincipal(new GenericIdentity(email), null);
as detailed here, but it doesn't work.
Note: This solution doesn't work for me, because of my specific situation: An Ajax login which changes the user identity on the server and hence every token that was generated before the login is invalid; this solution also doesn't apply because it addresses a different problem.