asp.net-mvc – 我如何编写一个ActionFilter来确保AntiForgeryTokens用于每个Post操作?

我想在每个HttpPost Action上使用一个ActionFilter来使用AntiForgeryTokens,该ActionFilter位于每个其他控制器继承的名为ControllerBase的控制器中.

我想通过创建一个继承自ValidateAntiForgeryToken的ActionFilter来做到这一点,该ActionFilter接受一个参数,告诉它要将自身应用的HTTP动词.然后,我想在ControllerBase上应用该过滤器,以确保在整个站点上检查AntiForgeryToken的每个POST操作.

我正在研究使用this solution,但是

> AuthorizationContext构造函数(ControllerContext)是一个过时的构造函数,我不知道如何使用推荐的AuthorizationContext(ControllerContext controllerContext,ActionDescriptor actionDescriptor)重建代码.
>认情况下,它似乎没有使用AntiForgeryToken,因为我收到以下错误:未提供所需的防伪标记或在每个帖子操作后无效.

我应该如何重写ActionFilter以满足当前的非过时标准,并在每个[HttpPost]动词上正确使用防伪标记

我是否必须在每种形式中都包含一个防伪标记(我在想)? (而不是自动生成 – 不要笑,我很好奇)更新:正如评论中指出的那样;是的,这必须在每个表格中完成.

以下是我的ControllerBase中的代码供参考:

[UseAntiForgeryTokenOnPostByDefault]
public class ControllerBase : Controller 
{
    [AttributeUsage(AttributeTargets.Method,AllowMultiple = false)]
    public class BypassAntiForgeryTokenAttribute : ActionFilterattribute
    {
    }

    [AttributeUsage(AttributeTargets.Class,AllowMultiple = false)]
    public class UseAntiForgeryTokenOnPostByDefault : ActionFilterattribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (ShouldValidateAntiForgeryTokenManually(filterContext))
            {
                var authorizationContext = new AuthorizationContext(filterContext.Controller.ControllerContext);

                //Use the authorization of the anti forgery token,//which can't be inhereted from because it is sealed
                new ValidateAntiForgeryTokenAttribute().OnAuthorization(authorizationContext);
            }

            base.OnActionExecuting(filterContext);
        }

        /// <summary>
        /// We should validate the anti forgery token manually if the following criteria are met:
        /// 1. The http method must be POST
        /// 2. There is not an existing [ValidateAntiForgeryToken] attribute on the action
        /// 3. There is no [BypassAntiForgeryToken] attribute on the action
        /// </summary>
        private static bool ShouldValidateAntiForgeryTokenManually(ActionExecutingContext filterContext)
        {
            var httpMethod = filterContext.HttpContext.Request.HttpMethod;

            //1. The http method must be POST
            if (httpMethod != "POST") return false;

            // 2. There is not an existing anti forgery token attribute on the action
            var antiForgeryAttributes =
                filterContext.ActionDescriptor.GetCustomAttributes(typeof (ValidateAntiForgeryTokenAttribute),false);

            if (antiForgeryAttributes.Length > 0) return false;

            // 3. There is no [BypassAntiForgeryToken] attribute on the action
            var ignoreAntiForgeryAttributes =
                filterContext.ActionDescriptor.GetCustomAttributes(typeof (BypassAntiForgeryTokenAttribute),false);

            if (ignoreAntiForgeryAttributes.Length > 0) return false;

            return true;
        }
    }
}

解决方法

您不需要实例化任何AuthorizationContext或调用OnAuthorization方法,只需:
if (ShouldValidateAntiForgeryTokenManually(filterContext))
{
    AntiForgery.Validate(filterContext.HttpContext,null);
}

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....