为何通过类型添加AutoValidateAntiForgeryTokenAttribute无法生效?
为什么ASP.NET Core中用类型添加AutoValidateAntiforgeryTokenAttribute过滤器会失效?
这个问题我之前踩过坑,咱们先把场景理清楚:
在ASP.NET Core里,当你用实例方式添加AutoValidateAntiforgeryTokenAttribute过滤器时,非GET请求的防伪造令牌验证能正常工作:
services.AddMvc(options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()) );
但一旦换成类型引用的方式——不管是用typeof还是泛型Add<T>方法——验证就完全没效果了:
// 无法生效 services.AddMvc(options => options.Filters.Add(typeof(AutoValidateAntiforgeryTokenAttribute)) ); // 同样无法生效 services.AddMvc(options => options.Filters.Add<AutoValidateAntiforgeryTokenAttribute>() );
问题出在哪?
核心原因是AutoValidateAntiforgeryTokenAttribute这个过滤器的构造函数需要依赖注入服务,但ASP.NET Core的过滤器系统在处理类型添加的过滤器时,默认会尝试用无参构造函数去实例化它。而这个属性根本没有无参构造函数,导致实例化失败,过滤器根本没被正确加载到请求管道里,自然不会生效。
怎么解决?
有两种靠谱的方式能让类型方式的过滤器正常工作:
1. 用ServiceFilterAttribute包装
先把过滤器注册到DI容器,再用ServiceFilter让框架从DI中获取实例:
// 第一步:把过滤器注册为Scoped服务 services.AddScoped<AutoValidateAntiforgeryTokenAttribute>(); // 第二步:用ServiceFilter添加到Mvc选项中 services.AddMvc(options => options.Filters.Add<ServiceFilter<AutoValidateAntiforgeryTokenAttribute>>() );
2. 直接用实例方式(最省心)
如果你的场景不需要动态依赖注入,直接用开头的实例添加方式是最稳妥的——毕竟它能确保过滤器被正确初始化,直接加入到请求管道里,不会有实例化失败的问题。
额外提一句
AutoValidateAntiforgeryTokenAttribute的作用是自动验证所有非GET、HEAD、OPTIONS、TRACE的请求。如果需要更细粒度的控制,你也可以考虑用ValidateAntiforgeryTokenAttribute(需要手动标记在Action或Controller上),或者自定义过滤器来调整验证逻辑。
内容的提问来源于stack exchange,提问作者Blisco
相关产品推荐
相关产品推荐

