Click here to Skip to main content
15,885,365 members
Articles / Web Development / HTML
Tip/Trick

Implementing AntiForgery Token in AJAXPOST

Rate me:
Please Sign up or sign in to vote.
4.18/5 (6 votes)
10 Jul 2015CPOL2 min read 23.6K   248   9   4
This is to implement anti forgery token with Ajax post in MVC Application

Table of Contents

  1. Introduction
  2. Steps to implementing Antiforgery token through AJAXPOST in MVC [Razor]
  3. Control Flow

Introduction

Antiforgery token is required where we need to implement CSRF [Cross-Site Request Forgery]. It is a simple trick. In Master page, Get the Token by using server code and store it as global JSON object with property name ‘RequestVerificationToken’, bind the token to the header of the Ajax post. In server side, create a filter that gets the token by property name ‘RequestVerificationToken’ and validate. Follow the below steps for better understanding.

Steps to Implementing Antiforgery Token Through AJAXPOST in MVC [Razor]

Step 1: Get Token Value in Master Page Through Server Code

JavaScript
@{
    string cookieToken, formToken;
    AntiForgery.GetTokens(null, out cookieToken, out formToken);
    var tokenHeaderValue = cookieToken + ":" + formToken;
}
  • cookieToken: token stored inside the cookie
  • formToken: token sent to your page for the forms
  • AntiForgery.GetTokens(); stores the token value inside the variable ‘cookieToken, formToken

Add the above code in your Master page or the page where you require antiforgery token.

Step 2: Assign the Token Value as Global Variable in JQuery

JavaScript
<script type="text/javascript">
        var TOKENHEADERVALUE = '@tokenHeaderValue';
</script>

Store ‘@tokenHeaderValue’ in the Global JQuery variable ‘TOKENHEADERVALUE’.

Place the above code in page where you placed Step 1 code.

Step 3: Setup the Ajax with Header

JavaScript
$(document).ready(function () {
        $.ajaxSetup({
            headers: {
                'RequestVerificationToken': TOKENHEADERVALUE
            },
        });
    });

Inside $.ajaxSetup({…. });, place the headers object with property ‘RequestVerificationToken’ contains the token value from the Global variable ‘TOKENHEADERVALUE’.

JavaScript
$.ajax({
url: url,// URL to the Action method
type: 'POST',//Type 'GET'/ 'POST'
contentType: 'application/json;charset=utf-8', // Content Type
data: dataObj,// Data to be sent as parameter
success: function (data) {alert('Success!');}, //Return to success property after 
                                               //successful return from the action method
error: function(data) { alert('Error!');}      //Return to error when there any error in Ajax call
});

This ‘$.ajaxSetup({…. });‘ adds the ‘headers’ as one more property to the above $.ajax call. Whenever the there is an Ajax call within the scope where ‘$.ajaxSetup({…. });‘ is specified, [i.e., if ajaxsetup is specified globally to the entire application, then it binds headers property to all Ajax calls throughout the application].

Step 4: Create a Custom Validation Filter

C#
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ValidateCustomAntiForgeryTokenAttribute : FilterAttribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        //throw new NotImplementedException();
    }
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext != null && filterContext.HttpContext != null && 
			filterContext.HttpContext.Request != null &&
            !string.IsNullOrEmpty(filterContext.HttpContext.Request.HttpMethod)
            && string.Compare(filterContext.HttpContext.Request.HttpMethod, "POST", true) == 0)
        {
            ValidateRequestHeader(filterContext.HttpContext.Request);
        }      
    }

    private void ValidateRequestHeader(HttpRequestBase request)
    {
        string cookieToken = "";
        string formToken = "";

        IEnumerable<string> tokenHeaders = request.Headers.GetValues("RequestVerificationToken");
        if (tokenHeaders != null && tokenHeaders.Count() > 0)
        {
            string[] tokens = tokenHeaders.First().Split(':');
            if (tokens.Length == 2)
            {
                cookieToken = tokens[0].Trim();
                formToken = tokens[1].Trim();
            }

            System.Web.Helpers.AntiForgery.Validate(cookieToken, formToken);
        }
    }
}

Create ValidateCustomAntiForgeryTokenAttribute filter and register in FilterConfig as filters.Add(new ValidateCustomAntiForgeryTokenAttribute());

C#
public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new ValidateCustomAntiForgeryTokenAttribute());
    }
}

This class is available inside App_Start folder in the MVC Project.

Step 5: Assign Filter to the Action Method Called in Ajax Post

C#
[HttpPost]
[ValidateCustomAntiForgeryToken]
public JsonResult IndexSingle(string data)
{
    return Json(data, JsonRequestBehavior.AllowGet);
}

Here, the filter checks before the control hits the action and validates the token proceed if token is valid, otherwise control will not go to the corresponding method.

Control Flow

  1. Request from the Ajax call $.ajax({});
  2. Hits the filter if it is a valid Ajax call.

    Control goes to:

    C#
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext != null && filterContext.HttpContext != null && 
             filterContext.HttpContext.Request != null &&
            !string.IsNullOrEmpty(filterContext.HttpContext.Request.HttpMethod)
            && string.Compare(filterContext.HttpContext.Request.HttpMethod, "POST", true) == 0)
        {
            ValidateRequestHeader(filterContext.HttpContext.Request);
        }  
    }
  3. In If() condition, it checks the request to the server is Ajax post request or not if the condition is true, then it calls ValidateRequestHeader(filterConte…….); method with the request as parameter.
    JavaScript
    private void ValidateRequestHeader(HttpRequestBase request)
    {
        string cookieToken = "";
        string formToken = "";
    
        IEnumerable<string> tokenHeaders = request.Headers.GetValues("RequestVerificationToken");
        if (tokenHeaders != null && tokenHeaders.Count() > 0)
        {
            string[] tokens = tokenHeaders.First().Split(':');
            if (tokens.Length == 2)
            {
                cookieToken = tokens[0].Trim();
                formToken = tokens[1].Trim();
            }
    
            System.Web.Helpers.AntiForgery.Validate(cookieToken, formToken);
        }
    }
  4. In this method, it separates the token from the headers with property name ["RequestVerificationToken"] specified in the $.ajaxSetup({}).
  5. Split the token value to get the cookieToken and formToken which is separated by ‘:
  6. Validate the token as System.Web.Helpers.AntiForgery.Validate(cookieToken, formToken);

If valid, the control proceeds to the action method called through $.ajax.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
Love to code and knowledge seeker.

Comments and Discussions

 
QuestionAll images are broken Pin
Tridip Bhattacharjee12-Jul-15 22:43
professionalTridip Bhattacharjee12-Jul-15 22:43 
AnswerRe: All images are broken Pin
Master-Ram13-Jul-15 5:05
professionalMaster-Ram13-Jul-15 5:05 
GeneralMy vote of 4 Pin
newton.saber10-Jul-15 5:01
newton.saber10-Jul-15 5:01 
GeneralRe: My vote of 4 Pin
Master-Ram10-Jul-15 7:22
professionalMaster-Ram10-Jul-15 7:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.