After some time of investigation I think I found some way how to get rid of this error for user. It is not perfect but at least not display error page:
I created filter based on HandleErrorAttribute
:
[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class LoginAntiforgeryHandleErrorAttribute : FilterAttribute, IExceptionFilter
{
#region Implemented Interfaces
#region IExceptionFilter
/// <summary>
/// </summary>
/// <param name="filterContext">
/// The filter context.
/// </param>
/// <exception cref="ArgumentNullException">
/// </exception>
public virtual void OnException(ExceptionContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (filterContext.IsChildAction)
{
return;
}
// If custom errors are disabled, we need to let the normal ASP.NET exception handler
// execute so that the user can see useful debugging information.
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
Exception exception = filterContext.Exception;
// If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
// ignore it.
if (new HttpException(null, exception).GetHttpCode() != 500)
{
return;
}
// check if antiforgery
if (!(exception is HttpAntiForgeryException))
{
return;
}
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "Index" },
{ "controller", "Home" }
});
filterContext.ExceptionHandled = true;
}
#endregion
#endregion
}
Then I applied this filter to Login POST action:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[LoginAntiforgeryHandleError]
public ActionResult Login(Login model, string returnUrl)
{
The main idea of this solution is to redirect anti-forgery exception to main index action. If user will still won't be unauthenticated it will show then login page if user will be already authenticated it will show index page.
UPDATE 1
There is one potential problem with this solution. If somebody is logging in with different credentials then on error it should be added additional login runtime - logout previous user and login new one. This scenario is not handled.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…