.NET MVC,在 ValidateAntiForgeryToken 检查失败后做一些事情
.NET MVC, Do something after ValidateAntiForgeryToken check fails
在我的表格中我有
@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
}
当 post 请求丢失令牌时,框架不会继续执行该方法。如果我想记录表单信息以供日后检查,我可以做什么以及在哪里?
[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
}
}
通过这种方式,您可以手动验证防伪标记,这样您就有机会让该方法执行。
另一种方法是创建一个自定义异常过滤器来捕获 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());
}
这对原发布者来说可能不是特别有用,但如果您在 .Net Core 2.2 或更高的世界中,防伪令牌失败将不会引发异常,而是会生成 AntiforgeryValidationFailedResult。因此,您将希望针对该结果而不是异常创建过滤器。
有关详细信息和代码示例,请参阅 。
在我的表格中我有
@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
}
当 post 请求丢失令牌时,框架不会继续执行该方法。如果我想记录表单信息以供日后检查,我可以做什么以及在哪里?
[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
}
}
通过这种方式,您可以手动验证防伪标记,这样您就有机会让该方法执行。
另一种方法是创建一个自定义异常过滤器来捕获 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());
}
这对原发布者来说可能不是特别有用,但如果您在 .Net Core 2.2 或更高的世界中,防伪令牌失败将不会引发异常,而是会生成 AntiforgeryValidationFailedResult。因此,您将希望针对该结果而不是异常创建过滤器。
有关详细信息和代码示例,请参阅