【发布时间】:2017-08-28 08:05:58
【问题描述】:
我想在 MVC 3 的 Global.asax 文件中实现 Anti-CSRF 令牌。 是否可以在 Gloabl.asax 文件中实现相同的功能。
【问题讨论】:
标签: c# asp.net-mvc asp.net-mvc-3 csrf global-asax
我想在 MVC 3 的 Global.asax 文件中实现 Anti-CSRF 令牌。 是否可以在 Gloabl.asax 文件中实现相同的功能。
【问题讨论】:
标签: c# asp.net-mvc asp.net-mvc-3 csrf global-asax
您似乎需要创建一个自定义过滤器类,通过检查HttpContext.Request.HttpMethod 请求,为所有POST 方法实现IAuthorizationFilter:
public class ValidateAntiForgeryTokenEveryPost : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext context)
{
if (context.HttpContext.Request.HttpMethod == "POST")
{
System.Web.Helpers.AntiForgery.Validate();
}
}
}
然后,在FilterConfig 类中添加新过滤器:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ValidateAntiForgeryTokenEveryPost());
}
}
还要确保自定义过滤器已在Global.asax 代码中注册:
protected void Application_Start()
{
// other settings
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
// other settings
}
通过使用上面给出的全局过滤,所有 POST 方法请求都会自动检查 AntiForgeryToken,无论视图页面中是否存在 @Html.AntiForgeryToken()。
附录 1:
可以从 CSRF 令牌检查中排除某些操作,您需要防止在存在自定义属性类时执行 Validate 方法。首先,创建一个自定义属性类进行验证检查:
[AttributeUsage(AttributeTargets.Method)]
public class ExcludeAntiForgeryCheckAttribute : Attribute
{
// other stuff
}
之后,使用ActionDescriptor.GetCustomAttributes 获取上面创建的自定义属性类型:
public class ValidateAntiForgeryTokenEveryPost : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext context)
{
// adapted from Darin Dimitrov (/a/34588606/)
bool isValidate = !context.ActionDescriptor.GetCustomAttributes(typeof(ExcludeAntiForgeryCheckAttribute), true).Any();
// use AND operator (&&) if you want to exclude POST requests marked with custom attribute
// otherwise, use OR operator (||)
if (context.HttpContext.Request.HttpMethod == "POST" && isValidate)
{
System.Web.Helpers.AntiForgery.Validate();
}
}
}
然后你可以装饰任何应该免除 CSRF 验证令牌的方法:
[HttpPost]
[ExcludeAntiForgeryCheck]
public ActionResult Index(ViewModel model)
{
// other stuff
return View(model);
}
参考资料:
【讨论】:
App_Start 目录或您想要的任何目录中创建,前提是使用该项目的根命名空间而不是ProjectName.App_Start 或ProjectName.FolderName。
我不这么认为。对于每个请求,我们需要检查令牌。 请尝试在视图文件中使用以下代码。
@Html.AntiForgeryToken()
【讨论】: