Override anti-forgery token errors on login page
What I ended up doing, and it seems to be working while still providing the same security, is to manually check the antiforgery token after checking if the user is logged in.
[HttpPost]
[AllowAnonymous]
//[ValidateAntiForgeryToken]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
// Skip the login process if the user is already logged in
if (User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Home");
}
// Check the anti forgery token now
System.Web.Helpers.AntiForgery.Validate();
...
There is an answer for concurrent login attempts originated from certain user:
How can I fix anti-forgery token was meant for user "", but the current user is "xxxx " error
If AntiForgeryToken exception comes when the user has too long time to fill in login page, simply redirect to that page and show a message explaining his/her session (i.e. security token) had expired.
[HttpPost]
[ValidateAntiForgeryToken]
[HandleError(View="Login", ExceptionType = typeof(HttpAntiForgeryException))]
public ActionResult Login(LoginModel model)
{
// some login processing stuff
}
If the exception comes from user's clicking back button, provide JS function on client-side which prevent the back button action on login page only:
<body onload="window.history.forward()">...</body>
// or wrap it inside a function
<script type="text/javascript">
function noBackOnLogin() {
window.history.forward();
history.pushState(null, document.title, url); // if you want to include Mobile Safari, see https://stackoverflow.com/a/34337617/6378815
}
</script>
<body onload="noBackOnLogin();" onpageshow="if (event.persisted) noBackOnLogin();">...</body>
For another case that certain user has already logged in, redirect to the index or somewhat page indicating their user name (with User.Identity.Name
).
I hope this explanation useful.