MVC 3 中的反 CSRF 实现
Anti-CSRF implementation in MVC 3
我想在 MVC 3 的 Global.asax 文件中实现反 CSRF 令牌。
是否可以在 Gloabl.asax 文件中实现相同的功能。
我不这么认为。对于每个请求,我们都需要检查令牌。
请尝试在视图文件中使用以下代码。
@Html.AntiForgeryToken()
看来您需要创建一个自定义过滤器 class,它通过检查 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
class 中添加新过滤器:
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
方法在存在自定义属性 class 时执行。首先,创建一个自定义属性 class 用于验证检查:
[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);
}
参考文献:
我想在 MVC 3 的 Global.asax 文件中实现反 CSRF 令牌。 是否可以在 Gloabl.asax 文件中实现相同的功能。
我不这么认为。对于每个请求,我们都需要检查令牌。 请尝试在视图文件中使用以下代码。
@Html.AntiForgeryToken()
看来您需要创建一个自定义过滤器 class,它通过检查 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
class 中添加新过滤器:
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
方法在存在自定义属性 class 时执行。首先,创建一个自定义属性 class 用于验证检查:
[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);
}
参考文献: