2017-08-28 100 views

回答

1

看来你需要的是通过检查HttpContext.Request.HttpMethod请求创建一个自定义过滤器类,它实现IAuthorizationFilter所有POST方法:

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(基于属性的版本)

+0

非常感谢。还有一个问题。我是MVC的新手,所以我不确定我需要创建自定义过滤器类的文件夹。你能告诉我这个吗? –

+0

我认为你的自定义过滤类可以在'App_Start'目录或你想要的任何目录下创建,只要使用了项目的根名称空间而不是'ProjectName.App_Start'或'ProjectName.FolderName'。 –

+0

非常感谢。@Tetsuya Yamamoto –

1

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

@ Html.AntiForgeryToken()

+0

我们可以在每个视图页面实现。但我想在Global.asax文件中实现相同的功能。 –