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);
}

参考文献:

Check CRSF token by default in ASP.NET MVC(标准版)

Securing all forms using AntiForgeryToken(基于属性的版本)