profile

Ajax and Anti-Forgery Tokens in Orchard CMS

ajax, POST, forgery

    I will be screwing around in  Orchard CMS perform a rockin' ajax POST operation and will get hit with an “anti-forgery token not supplied” type of error. If this happens  you probably look at your code,  look at the ajax call, and think “What the what?!” Well, the answer lies in the inclusion of the __RequestVerificationToken variable and it being assigned a special value given to us by the Orchard framework.

Solution:

I will go from the bottom up to display how this works, which means I will start with the Migration.cs file and the definition of a Person object (after I make a module of course, but I will leave that to you dear reader to figure out). The Migration.cs file will walk through the creation of a Person table. I am not making a CMS type of content item, but am instead using Orchard as more of a website framework at this point. 

Example.Forgery/Migration.cs



If we take this line by line we see the [Admin] attribute which allows this thing to push views to the Admin side of the house. The constructor is being injected with an IRepository<Person> and this repository can call into NHib to create a new Person. The second Create method is overloaded, the [ActionName("Create")] decorator allows this overloaded method to exist only for POST requests (the other one is only GET requests). 

Now that we have that taken care of, let's look at the view now.

Examples.Forgery/Views/Person/Create.cshtml

First off, lets look at the Scripts that I am adding (I will be adding jQuery and KnockoutJS)


You might be saying "where did he define the 'jQueryCDN' and 'KnockoutCDN' scripts from?" Well, you go to the ResourceManifest for those! To the Manifest!!!

Examples.Forgery/ResourceManifest.cs

This manifest just allows me to drop a fast Script.Require() and it all resolves nicely!

Back to the View....


Now that we have that all lookin' good, let's go ahead and look at the script that I added at the bottom of the view (it is some KnockoutJS code that wil tie up the click event on the button to a method 'Model.AddPerson' that will invoke the $.ajax call).

If I were to run the site and click the button, it would fire the Create method on my Person controller, and I would meet this:


OUCH!

Okay, so where do we go from here?

What the hell do we do now?

Welp, I'll tell what we will do, we will add an extra property to our javascript object "Person." This extra property will be __RequestVerificationToken:

When I post this to the server now, what does the posted request look like??

{

"Id":"",

"FirstName":"lkj",

"LastName":"lkjh",

"__RequestVerificationToken":"lh/hP/OkgVeTA+GnKP1sK1OXCQp ... <brevity />"

}

That seemed to work out well, just using the @Html.AntiForgeryTokenValueOrchard() call. Now though, I need to update my model binding on the back end to support this new property being passed in:

Example.Forgery/ViewModels/PersonViewModel.cs


Now the method has to be updated (the method being the Create method)

Example.Forgery/Controllers/PersonController



2 Comments

Add a Comment