I am using the code as below of this post:
First I will fill an array variable with the correct values for the controller action.
Using the code below I think it should be very straightforward by just adding the following line to the JavaScript code:
data["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val();
The <%= Html.AntiForgeryToken() %>
is at its right place, and the action has a [ValidateAntiForgeryToken]
But my controller action keeps saying: "Invalid forgery token"
What am I doing wrong here?
Code
data["fiscalyear"] = fiscalyear;
data["subgeography"] = $(list).parent().find('input[name=subGeography]').val();
data["territories"] = new Array();
$(items).each(function() {
data["territories"].push($(this).find('input[name=territory]').val());
});
if (url != null) {
$.ajax(
{
dataType: 'JSON',
contentType: 'application/json; charset=utf-8',
url: url,
type: 'POST',
context: document.body,
data: JSON.stringify(data),
success: function() { refresh(); }
});
}
You don't need the ValidationHttpRequestWrapper solution since MVC 4. According to this link.
Here is my solution:
I have resolved it globally with RequestHeader.
where the requestVerificationTokenVariable is an variable string that contains the token value. Then all ajax call send the token to the server, but the default ValidateAntiForgeryTokenAttribute get the Request.Form value. I have writed and added this globalFilter that copy token from header to request.form, than i can use the default ValidateAntiForgeryTokenAttribute:
This work for me :)
I was just implementing this actual problem in my current project. I did it for all Ajax POSTs that needed an authenticated user.
First off, I decided to hook my jQuery Ajax calls so I do not to repeat myself too often. This JavaScript snippet ensures all ajax (post) calls will add my request validation token to the request. Note: the name __RequestVerificationToken is used by the .NET framework so I can use the standard Anti-CSRF features as shown below.
In your Views where you need the token to be available to the above JavaScript code, just use the common HTML-Helper. You can basically add this code wherever you want. I placed it within a if(Request.IsAuthenticated) statement:
In your controller simply use the standard ASP.NET MVC anti-CSRF mechanism. I did it like this (though I actually used a salt).
With Firebug or a similar tool you can easily see how your POST requests now have a __RequestVerificationToken parameter appended.
You can't validate an content of type contentType: 'application/json; charset=utf-8' because your date will be uploaded not in the Form property of the request, but in the InputStream property, and you will never have this Request.Form["__RequestVerificationToken"].
This will be always empty and validation will fail.
Check out Dixin's Blog for a great post on doing exactly that.
Also, why not use $.post instead of $.ajax?
Along with the jQuery plugin on that page, you can then do something as simple as:
You won't ever have to validate an AntiForgeryToken when you receive posted JSON.
The reason is that AntiForgeryToken has been created to prevent CSRF. Since you can't post AJAX data to another host and HTML forms can't submit JSON as the request body, you don't have to protect your app against posted JSON.