AngularJS, JSON and AntiForgeryToken in ASP.NET MVC

Views: 5583
Comments: 3
Like/Unlike: 1
Posted On: 02-Jan-2017 03:04 

Share:   fb twitter linkedin
NiceOne...
1390 Points
18 Posts

Introduction

To prevent Cross-Site Request Forgery (CSRF) Attacks we use ASP.NET MVC’s AntiForgeryToken. It generates a hidden form field (anti-forgery token) that is validated when the form is submitted. It is work fine with normal form submittion but It is not work with $http post with angular or $.post with jquery. This article will be helpful  to validate AntiForgeryToken with $http (angularjs) by creating custom validator.

Description

I) Create Filter/Attribute 'CustomValidateAntiForgeryToken':

We will process the request, extract the tokens from the request header. Then call the AntiForgery.Validate method to validate the tokens. The Validate method throws an exception if the tokens are not valid. We create a custom attribute for this. Right click on Filters folder and add new class “CustomValidateAntiForgeryToken.cs”

using System;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
namespace EventCombo.ActionFilters
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CustomValidateAntiForgeryToken : FilterAttribute, IAuthorizationFilter
{
private void ValidateRequestHeader(HttpRequestBase request)
{
string cookieToken = String.Empty;
string formToken = String.Empty;
string tokenValue = request.Headers["RequestVerificationToken"];
if (!String.IsNullOrEmpty(tokenValue))
{
string[] tokens = tokenValue.Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
}
public static string GetAntiForgeryToken()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
public void OnAuthorization(AuthorizationContext filterContext)
{
try
{
ValidateRequestHeader(filterContext.HttpContext.Request);
}
catch (HttpAntiForgeryException ex)
{
throw new HttpAntiForgeryException("Anti forgery token cookie not found. Error: " + ex.Message);
}
}
}
}

 In the above class we can see a static method GetAntiForgeryToken. We will use it to generate token later.

II) In Angular View

Add a hidden field with value as Antiforgery token generated by GetAntiForgeryToken method:

<form name="personalInfoForm" novalidate>
<input id="antiForgeryToken" data-ng-model="AntiForgeryToken" type="hidden" data-ng-init="AntiForgeryToken='@CustomValidateAntiForgeryToken.GetAntiForgeryToken()'" />

III) In Angular Service JS

Use hidden field model to set header:

this.updateMyAccount = function (UserDetail, $scope) {
var response = $http({
method: "post",
datatype: "data.json",
data: { myAccount: UserDetail },
url: "/Account/UpdateAccountDetail",
headers: {
'RequestVerificationToken': $scope.AntiForgeryToken,
}
});
return response;
};

 

IV) In MVC Action

Put custom attribute 'CustomValidateAntiForgeryToken': 

[HttpPost]
[Authorize]
[CustomValidateAntiForgeryToken]
public ActionResult UpdateAccountDetail(MyAccountViewModel myAccount)
{

 

V) Now Build and test. That's it.

Conclusion

We have seen see how to genrate and validate AntiForgeryToken with angular js. It is very useful when we are working in architecture way where we can’t access value of controls in Ajax request directly.

 

3 Comments
Hi,

This method to prevent CSRF does not work in my project, my application throws exception:

System.Web.Mvc.HttpAntiForgeryException: 'Anti forgery token cookie not found. Error: The required anti-forgery cookie "__RequestVerificationToken" is not present.'

Did someone try this method in own project ?

Marcin
23-Jul-2017 at 04:54
Are you adding header 'RequestVerificationToken'? Please check Step III

Brian
23-Jul-2017 at 06:38
great..

nik
11-May-2018 at 20:39
 Log In to Chat