I have a class which is used to perform Validation of Antiforgery tokens where the payload is Json. That class looks like this (from Phil Haacked):
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (ReferenceEquals(filterContext, null)) throw new ArgumentNullException("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 = request.Cookies[AntiForgeryConfig.CookieName];
var cookieValue = ReferenceEquals(antiForgeryCookie, null) ? null : antiForgeryCookie.Value;
AntiForgery.Validate(cookieValue, request.Headers[AntiForgeryConfig.CookieName]);
}
else
{
new ValidateAntiForgeryTokenAttribute().OnAuthorization(filterContext);
}
}
}
}
This is the first Angular project I am using it on and it is not throwing an exception where I would expect it to. For example, the value in the header differs from the value in the cookie and the call to AntiForgery.Validate
proceeds without exception.
The anti-forgery token is rendered in the shell view (i.e. Index.cshtml) and it is added to the headers in Angular's module run function:
// Handle routing errors and success events
theApp.run(['$http', '$route', '$rootScope', '$q', 'routeOverlord',
function ($http, $route, $rootScope, $q, routeOverlord) {
// Include $route to kick start the router.
routeOverlord.setRoutingHandlers();
// Include AntiForgeryToken to prevent CSRF attacks
$http.defaults.headers.common['__RequestVerificationToken'] = angular.element('input[name="__RequestVerificationToken"]').val();
}]);
Is this a known thing? Happy to provide a Fiddler screenshot of the differing strings in the cookie and header if requested.
Cheers
The cookie token and the form token (the one in the headers in your case) are not supposed to be identical (it would be easier to fake).
The cookie token contains a random blob. The form token contains the same blob, plus some identity data (and optionally some additional data).
AntiForgery.Validate()
checks that both blobs are identical, and that the other data in the form token corresponds to the identity data and the optional additional data.