0

I am securing my application against cross-site scripting using anti forgery token Development environment is VS 2012, MVC4, knockout

I have placed anti-forgery token as follows

<form id="__AjaxAntiForgeryForm" action="#" method="post"><%= Html.AntiForgeryToken()%></form>  

In my ajax call I also want to send data. My ajax call is as follows

            $.ajax({
                url: VirtualDir + '/Tasks/StartTask/',
                asynch: false,
                type: 'POST',
                data: { "__RequestVerificationToken": token, oTaskData: JSON.stringify(item), whichTab: self.CurrentTab },
                success: function (data) {
                    InitializeData(data);
                    self.LoadData(data);
                }
            })
        };

My controller code is as follows

    [ValidateAntiForgeryToken]
    [Authorize]
    public JsonResult StartTask(TaskData oTaskData, string whichTab)
    {
        int TaskID = oTaskData.TaskID;
        int LoggedInEmployeeID = Convert.ToInt32(System.Web.HttpContext.Current.Session["EmployeeID"]);
        TaskRepository oTaskRepository = new TaskRepository();
        return Json(oTaskRepository.TaskChangeStatus(TaskID, LoggedInEmployeeID, TaskConstants.IN_PROGRESS, whichTab), JsonRequestBehavior.AllowGet);
    }

In controller, value of whichTab parameter is received but oTaskData is null If I remove anti-forgery token then data is received properly in controller

How can I use antiforgery token along with JSON data?

1 Answers1

0

When sending multiple values in JSON. You have stringify like this:

I am separating JSON string from the Ajax Request to make it clear.

    var sData = JSON.stringify({
       __RequestVerificationToken : token,
       oTaskData: item,
       whichTab: self.CurrentTab
    });   

In Ajax Request Add this: contentType: 'application/json', To show you are sending Json data.

and you are returning Json, so also dataType: 'json'

 $.ajax({
      url: VirtualDir + '/Tasks/StartTask/',
      asynch: false,
      type: 'POST',
      data: sData,
      contentType: 'application/json',
      dataType: 'json'
                success: function (data) {
                    InitializeData(data);
                    self.LoadData(data);
                }
            });

EDIT:

If the Above doesn't work then use Answer here: Use the HEADER of Ajax request.

https://stackoverflow.com/a/24394578/1910735

var headers = {};
headers['__RequestVerificationToken'] = token;

$.ajax({
    type: 'POST',
    url: '/MyTestMethod',
    contentType: 'application/json; charset=utf-8',
    headers: headers,
    data: JSON.stringify({
         oTaskData: item,
           whichTab: self.CurrentTab
    }),
    dataType: "json",
    success: function () {},
    error: function (xhr) {}
});

You will have to create this Attribute Class : ValidateJsonAntiForgeryTokenAttribute, You can see in the answer: https://stackoverflow.com/a/24394578/1910735

Community
  • 1
  • 1
Dawood Awan
  • 7,051
  • 10
  • 56
  • 119