Asp.net mvc 5 ValidateAntiForgeryToken无法使用asp.net mvc和ajax post

Asp.net mvc 5 ValidateAntiForgeryToken无法使用asp.net mvc和ajax post,asp.net-mvc-5,asp.net-core-mvc,antiforgerytoken,asp.net-mvc-5.1,Asp.net Mvc 5,Asp.net Core Mvc,Antiforgerytoken,Asp.net Mvc 5.1,我有一个使用.NET4.5.1的ASP.NETMVC5应用程序。该应用程序有几个jqueryajaxpost方法将数据发布到服务器。为了防止跨站点请求伪造(XSRF),我在_layout.cshtml中添加了以下内容 @Html.AntiForgeryToken() 还有javascript,它在HttpHeader中发送带有所有ajax帖子的令牌 $(document).ajaxSend(function (event, jqXHR, ajaxOptions) {

我有一个使用.NET4.5.1的ASP.NETMVC5应用程序。该应用程序有几个jqueryajaxpost方法将数据发布到服务器。为了防止跨站点请求伪造(XSRF),我在_layout.cshtml中添加了以下内容

 @Html.AntiForgeryToken()
还有javascript,它在HttpHeader中发送带有所有ajax帖子的令牌

$(document).ajaxSend(function (event, jqXHR, ajaxOptions) {
            if (ajaxOptions.type === 'POST') {
                jqXHR.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val());
            }                
        });
然后在控制器动作方法中,我有

    [ValidateAntiForgeryToken]        
    [HttpPost]
    public ActionResult Save(MyModel model)
    {
       //save and return json data
    }
但是,ValidateAntiForgeryToken异常

所需的防伪表单字段“\uu RequestVerificationToken”为 不在场

我验证了
\uuu RequestVerificationToken
被添加到每个Ajax帖子的httpheader中

我有另一个应用程序是使用ASP.NET Core开发的,我在那里有相同的功能(除了标题名是
RequestVerificationToken
而不是
\uu RequestVerificationToken
),它一直在ASP.NET Core中工作


当令牌包含在标头中时,为什么ASP.NET MVC中不使用相同的功能?ASP.NET Core和ASP.NET MVC 5中的ValidateAntiForgeryToken有什么不同吗?

要解决您的问题,除了setRequestHeader之外,所有内容都保持不变。在请求正文中传递\uuu RequestVerificationToken

data: {
                __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val(),
                // Other properties of data
            },

要解决您的问题,除了setRequestHeader之外,所有内容都保持不变。在请求正文中传递\uuu RequestVerificationToken

data: {
                __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val(),
                // Other properties of data
            },

为了解决我的问题,我已经实现了自定义ValidateAntiForgeryToken。我已决定在标题中包含令牌

  • 我在整个应用程序中使用了几种ajax POST方法,因此 将其添加到每个操作方法中,我希望全局验证它
  • 在客户端,我希望为每个ajax隐式地包含令牌 发布请求。(应用程序也有剑道网格,这使得ajax post请求(获取数据)
  • ajax post
    数据
    可以是json对象或序列化形式,这 将
    \uu RequestVerificationToken
    添加到
    数据中
    棘手的(不是不可能的),尤其是当我想处理它的时候
    全球范围内
  • 这是我的完整代码

    过滤器

    public class ValidatePostAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
        {
            private const string _tokenKey = "__RequestVerificationToken";
            public void OnAuthorization(AuthorizationContext filterContext)
            {
                if (filterContext == null)
                {
                    throw new ArgumentNullException("filterContext");
                }
    
                if (filterContext.HttpContext.Request.HttpMethod.ToUpper() == "POST")
                {
                    if (filterContext.HttpContext.Request.IsAjaxRequest())
                    {
                        if (filterContext.HttpContext.Request.Cookies.Get(_tokenKey) == null ||
                        filterContext.HttpContext.Request.Headers.Get(_tokenKey) == null)
                        {
                            throw new HttpPostAntiForgeryException("Invalid Verification Token.");
                        }
    
                        AntiForgery.Validate(filterContext.HttpContext.Request.Cookies[_tokenKey].Value, filterContext.HttpContext.Request.Headers[_tokenKey]);
                    }                
                }
            }
        }
    
    例外情况

    public sealed class HttpPostAntiForgeryException : HttpException
    {
        public HttpPostAntiForgeryException()
        {
        }
        public HttpPostAntiForgeryException(string message) : base(message)
        {
        }
    }
    
     $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
                    if (originalOptions.type === "POST")
                        jqXHR.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val());
                });
    
    全局添加过滤器

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new AuthorizeAttribute() { Order = 0 });
            filters.Add(new ValidatePostAntiForgeryTokenAttribute() { Order = 1 });
        }
    }
    
    \u layout.cshtml-js添加令牌

    public sealed class HttpPostAntiForgeryException : HttpException
    {
        public HttpPostAntiForgeryException()
        {
        }
        public HttpPostAntiForgeryException(string message) : base(message)
        {
        }
    }
    
     $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
                    if (originalOptions.type === "POST")
                        jqXHR.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val());
                });
    
    在布局.cshtml中添加令牌

      @Html.AntiForgeryToken()
    

    为了解决我的问题,我已经实现了自定义ValidateAntiForgeryToken。我已决定在标题中包含令牌

  • 我在整个应用程序中使用了几种ajax POST方法,因此 将其添加到每个操作方法中,我希望全局验证它
  • 在客户端,我希望为每个ajax隐式地包含令牌 发布请求。(应用程序也有剑道网格,这使得ajax post请求(获取数据)
  • ajax post
    数据
    可以是json对象或序列化形式,这 将
    \uu RequestVerificationToken
    添加到
    数据中
    棘手的(不是不可能的),尤其是当我想处理它的时候
    全球范围内
  • 这是我的完整代码

    过滤器

    public class ValidatePostAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
        {
            private const string _tokenKey = "__RequestVerificationToken";
            public void OnAuthorization(AuthorizationContext filterContext)
            {
                if (filterContext == null)
                {
                    throw new ArgumentNullException("filterContext");
                }
    
                if (filterContext.HttpContext.Request.HttpMethod.ToUpper() == "POST")
                {
                    if (filterContext.HttpContext.Request.IsAjaxRequest())
                    {
                        if (filterContext.HttpContext.Request.Cookies.Get(_tokenKey) == null ||
                        filterContext.HttpContext.Request.Headers.Get(_tokenKey) == null)
                        {
                            throw new HttpPostAntiForgeryException("Invalid Verification Token.");
                        }
    
                        AntiForgery.Validate(filterContext.HttpContext.Request.Cookies[_tokenKey].Value, filterContext.HttpContext.Request.Headers[_tokenKey]);
                    }                
                }
            }
        }
    
    例外情况

    public sealed class HttpPostAntiForgeryException : HttpException
    {
        public HttpPostAntiForgeryException()
        {
        }
        public HttpPostAntiForgeryException(string message) : base(message)
        {
        }
    }
    
     $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
                    if (originalOptions.type === "POST")
                        jqXHR.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val());
                });
    
    全局添加过滤器

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new AuthorizeAttribute() { Order = 0 });
            filters.Add(new ValidatePostAntiForgeryTokenAttribute() { Order = 1 });
        }
    }
    
    \u layout.cshtml-js添加令牌

    public sealed class HttpPostAntiForgeryException : HttpException
    {
        public HttpPostAntiForgeryException()
        {
        }
        public HttpPostAntiForgeryException(string message) : base(message)
        {
        }
    }
    
     $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
                    if (originalOptions.type === "POST")
                        jqXHR.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val());
                });
    
    在布局.cshtml中添加令牌

      @Html.AntiForgeryToken()
    

    @VahidN的可能重复-这不是同一个问题。我已经通过提供的链接之前。可能重复的@VahidN它不是同一个问题。我已经通过提供的链接之前。是的,在asp.net mvc如果我添加到数据,那么它的工作?然而,我猜在asp.net核心中,无论是添加
    数据
    还是添加
    标题
    ,它都可以工作。为了解决我的问题,我实现了自定义ValidateAntiForgeryTokenAttribute.Asp.net core检查了Asp.net mvc中的标头和正文中的token.yes如果我添加到数据中,那么它是否工作?然而,我猜在asp.net核心中,无论是添加
    数据
    还是添加
    标题
    ,它都可以工作。为了解决我的问题,我实现了自定义ValidateAntiForgeryTokenAttribute.Asp.net核心检查令牌的头和体。