gpt4 book ai didi

c# - 一种在 MVC 4 应用程序中正确处理 HttpAntiForgeryException 的方法

转载 作者:IT王子 更新时间:2023-10-29 04:03:44 26 4
gpt4 key购买 nike

场景如下:

我有一个登录页面,当用户签名时,它会被重定向到主应用程序页面。然后用户正在使用浏览器后退按钮,现在他在登录页面上。他尝试再次登录,但现在抛出异常:

HttpAntiForgeryException (0x80004005): The provided anti-forgery token was meant for user "", but the current user is "userName".

我知道这与缓存有关。我使用自定义 NoCache 过滤器禁用了登录操作的浏览器缓存,该过滤器设置了所有必需的 header - 无缓存、无存储、必须重新验证等。但是

  • 这不适用于所有浏览器
  • 尤其是 Safari(大多数情况下是移动设备)完全忽略此类设置

我将尝试破解并强制 safari 移动版刷新,但这不是我所期望的。

我想知道我是否可以:

  • 在不向用户显示任何问题存在的情况下处理异常(对用户完全透明)
  • 通过替换防伪 token 用户名来防止此问题,如果我与浏览器缓存相关的黑客攻击将在下一版本的浏览器中停止工作,这将允许用户再次登录而不会出现此异常。
  • 我真的不想依赖浏览器行为,因为每个浏览器的行为都不同。

更新 1

澄清一下,我知道如何处理 MVC 中的错误。问题是这种处理错误根本不能解决我的问题。错误处理的基本思想是重定向到带有友好消息的自定义错误页面。但我想防止这个错误发生,而不是以用户可见的方式处理它。通过句柄,我的意思是捕获使用户名替换或其他合适的操作,然后继续登录。

更新 2

我在下面添加了适合我的解决方案。

最佳答案

经过一段时间的调查,我想我找到了一些方法来为用户消除这个错误。它并不完美,但至少不显示错误页面:

我根据 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
}

然后我将此过滤器应用于登录 POST 操作:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[LoginAntiforgeryHandleError]
public ActionResult Login(Login model, string returnUrl)
{

该解决方案的主要思想是将防伪异常重定向到主索引操作。如果用户仍未通过身份验证,它将显示 login 页面,如果用户已经通过身份验证,它将显示 index 页面。

更新 1此解决方案存在一个潜在问题。如果有人使用不同的凭据登录,那么在出错时应该添加额外的登录运行时 - 注销以前的用户并登录新用户。不处理这种情况。

关于c# - 一种在 MVC 4 应用程序中正确处理 HttpAntiForgeryException 的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12967917/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com