Thursday, 13 February 2014

How to create customized Antiforgery token in MVC, RAZOR

     Steps to create customized Antiforgery token in MVC, RAZOR

1)    Add an extension method for HtmlHelper Class that will help us to generate Customized Antiforgery token control

2)    Add newly created CusomizedAntiforgerytoken() control in view page
3)    Add token.js library reference in view
4)    Add Customized Antiforgery token value for all Ajax based post present in view using tokenfix() method of token.js
5)    Handle Authorization of Customized Antiforgery token in MVC's OnAuthorization() method
6)    Add  [HttpPost],[ValidateAntiForgeryToken()] attributes in required controller methods



1)   Step 1: Add an extension method for HtmlHelper Class that will help us to generate Customized Antiforgery token control
          ClassFile : Exten.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
using System.Web.Mvc;
using System.Net;

namespace Web.Helper
{
    public static class Exten
    {
        public static MvcHtmlString CusomizedAntiforgerytoken(this HtmlHelper html)
        {
            string token = HttpUtility.HtmlEncode(Guid.NewGuid().ToString());
            string dha = @"<input name='__RequestVerificationToken_custom'
            type='hidden' value='" + token + "' />";
            HttpContext.Current.Session["__RequestVerificationToken_custom"] = token;
            return MvcHtmlString.Create(dha);
        }
    }
}


2)   Step 2: newly created CusomizedAntiforgerytoken() control in view page
        ViewName:  WebPage.cshtml
   <form id="frm1" title="" method="post" >
      @Html.IRISAntiforgerytoken()
       //put other form controls
    <input class="button" type="button" id="SubmitForm" value="SubmitForm" />
   </form>

3)   Step 3: Add token.js library reference in view
              ViewName:  WebPage.cshtml
<script src="@Url.Content("~/token.js")" type="text/javascript"></script>

      JavaScript File: token.js

var tr;
function tokenfix(tr) {
    debugger;
    var token = $('[name=__RequestVerificationToken_custom]').val();
    tr.__RequestVerificationToken_custom = token;
    return tr;
}
//Below given method is not in use, its for adding token in request headers
function GetTokenHeader() {
    debugger;
    var token = $('input[name=__RequestVerificationToken_custom]').val();
    var headers = {};
    headers["__RequestVerificationToken_custom"] = token;
    return headers;
}



4)   Step 4: Add Customized Antiforgery token value for all Ajax based post present in view using tokenfix() method of token.js
  JavascriptFileName:  WebPage.js
//tokenfix is function defined in token.js to add Customized Antforgery token  //(__RequestVerificationToken_custom) in request
    $.ajax({
        url: '/ControllerName/ControllerNameMethodName',
        type: "POST",
        dataType: 'String',
        data: tokenfix({ Parameter: "ParameterValue" }), 
        success: function (result) {
        }


5)   Step 5: Handle Authorization of Customized Antiforgery token in MVC's OnAuthorization() method

After creating customized Antiforgery token, we need to handle submission of forms using newly created customized token with the help of OnAuthorization(AuthorizationContext obj) method of Class AuthorizeAttribute present in MVC.
On overriding OnAuthorization() method , we can decide what type of post needs to be checked using below given methods.

For Post request
request.HttpMethod == WebRequestMethods.Http.Post

For Ajax request
request.IsAjaxRequest()



          ClassFile : ValidateAntiForgeryTokenOnAllPosts.cs
public class ValidateAntiForgeryTokenOnAllPosts : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            //  Only validate POSTs
            if (request.HttpMethod == WebRequestMethods.Http.Post)
            {
                //  Ajax POSTs and normal form posts have to be treated differently when it comes
                //  to validating the AntiForgeryToken
                if (request.IsAjaxRequest())
                {
                    var antiForgeryCookie = filterContext.HttpContext.Session["__RequestVerificationToken_custom"];

                    #region For passing Custom token via Headers use commented code
                    //if (antiForgeryCookie.ToString().ToLower().Trim() == request.Headers["__RequestVerificationToken_custom"].ToString().ToLower().Trim())
                    //in this case, we need to pass __RequestVerificationToken_custom via request headers using Jquery but it never works for all browsers
                    #endregion

                    if (antiForgeryCookie.ToString().ToLower().Trim() == request["__RequestVerificationToken_custom"].ToString().ToLower().Trim())
                    {
                    }
                    else
                    {
                        throw new Exception("Invalid Request");
                    }
                }
                else
                {
                    new ValidateAntiForgeryTokenAttribute()
                        .OnAuthorization(filterContext);
                }
            }
        }
    }


6)   Step 6: Add  [HttpPost],[ValidateAntiForgeryToken()] attributes in required controller methods

[HttpPost()]
[ValidateAntiForgeryToken()]
public ActionResult ControllerNameMethodName(string Parameter)
{
    //Method body as per need
}




No comments:

Post a Comment