【问题标题】:Anti-CSRF implementation in MVC 3MVC 3 中的反 CSRF 实现
【发布时间】: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


    【解决方案1】:

    您似乎需要创建一个自定义过滤器类,通过检查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);
    }
    

    参考资料:

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

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

    【讨论】:

    • 非常感谢。还有一个问题。我是 MVC 的新手,所以我不确定我需要在哪个文件夹下创建自定义过滤器类。你能建议我吗?
    • 我认为您的自定义过滤类可以在App_Start 目录或您想要的任何目录中创建,前提是使用该项目的根命名空间而不是ProjectName.App_StartProjectName.FolderName
    • 非常感谢.. @Tetsuya Yamamoto
    • 我想单独忽略主页的 CSRF 检查。因为我们正在为我们的应用程序使用 SSO 机制。所以它在主页中抛出异常。有没有可能解决这个问题。
    • @Ask_SO 我在“附录”部分更新了附加信息。检查它是否满足您的要求。
    【解决方案2】:

    我不这么认为。对于每个请求,我们需要检查令牌。 请尝试在视图文件中使用以下代码。

    @Html.AntiForgeryToken()

    【讨论】:

    • 我们可以在每个视图页面中实现。但我想在 Global.asax 文件中实现相同的功能。
    猜你喜欢
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 2017-11-22
    • 2020-02-05
    • 2020-07-19
    • 2011-06-05
    • 1970-01-01
    • 2011-10-12
    相关资源
    最近更新 更多