Asp.net mvc 5 ValidateAntiForgeryToken无法使用asp.net mvc和ajax post
我有一个使用.NET4.5.1的ASP.NETMVC5应用程序。该应用程序有几个jqueryajaxpost方法将数据发布到服务器。为了防止跨站点请求伪造(XSRF),我在_layout.cshtml中添加了以下内容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) {
@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。我已决定在标题中包含令牌
数据
可以是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。我已决定在标题中包含令牌
数据
可以是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核心检查令牌的头和体。