.NET MVC,在ValidateAntiForgeryToken检查失败后执行某些操作

时间:2018-05-25 19:08:56

标签: c# .net asp.net-mvc antiforgerytoken

我的表格中有

@Html.AntiForgeryToken()

并且接收控制器操作已

    [HttpPost, ValidateAntiForgeryToken]  
    public ActionResult Login(LoginViewModel model)  
    {
      //if detects a post request missing token, 
      //I wish to log form info for later inspection
    }

当发布请求丢失令牌时,框架不会进入该方法。如果我希望记录表格信息以供日后检查,我该怎么办?在哪里?

3 个答案:

答案 0 :(得分:3)

另一种方法是创建一个自定义异常过滤器来捕获AntiForgery异常并从那里记录表单详细信息,详情如下:

public class AntiForgeryExceptionAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        // ANTIFORGERY TOKEN NOT PRESENT
        if (!filterContext.ExceptionHandled && filterContext.Exception is HttpAntiForgeryException)
        {
            var request = new HttpRequestWrapper(System.Web.HttpContext.Current.Request);
            // Use your own logging service to log the results
            var _logger = new LoggingService();
            foreach (var key in request.Form.AllKeys)
            {
                var value = request.Form[key];
                // "key" is the form input name and "value" is the form input value
                _logger.Log("~~> " + key + " ==> " + value);
            }

            filterContext.ExceptionHandled = true;
        }
    }
}

并在global.asax注册自定义过滤器:

protected void Application_Start()
{
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    GlobalFilters.Filters.Add(new AntiForgeryExceptionAttribute());
}

答案 1 :(得分:2)

 [HttpPost]
 public async Task<IActionResult> Method(int id)
 {
        var formParameters = await Context.Request.ReadFormAsync();
        var requestVerification = formParameters["RequestVerificationToken"];
        string cookieToken = null;
        string formToken = null;

        if (!string.IsNullOrWhiteSpace(requestVerification))
        {
        var tokens = requestVerification.Split(':');

        if (tokens != null && tokens.Length == 2)
        {
            cookieToken = tokens[0];
            formToken = tokens[1];
        }


        var antiForgery = Context.RequestServices.GetService<AntiForgery>();
        try
        {
            antiForgery.Validate(Context, new AntiForgeryTokenSet(formToken, cookieToken))}
        catch
        {
           //log
        }
  }

这样您就可以手动验证防伪标记,这样您就有机会让方法执行。

答案 2 :(得分:0)

这对于原始张贴者可能不是特别有用,但是如果您在.Net Core 2.2或更高版本中,则防伪令牌失败不会引发异常,而是会生成AntiforgeryValidationFailedResult。因此,您将改为针对该结果而不是针对异常创建过滤器。

有关更多详细信息和代码示例,请参见this answer