Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Implementing AntiForgery Token in AJAXPOST

0.00/5 (No votes)
10 Jul 2015 1  
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

@{
    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

<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

$(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’.

$.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

[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());

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

[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:

    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.
    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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here