Angular against Asp.Net WebApi, implement CSRF on the server

Your code seems to be fine. The only thing is, you don’t need most of the code you have as web.api runs “on top” of asp.net mvc, and latter has built in support for anti-forgery tokens.

In comments dbrunning and ccorrin express concerns that you only able to use build in AntiForgery tokens only when you are using MVC html helpers. It is not true. Helpers can just expose session based pair of tokens that you can validate against each other. See below for details.

UPDATE:

There is two methods you can use from AntiForgery:

  • AntiForgery.GetTokens uses two out parameters to return cookie token and form token

  • AntiForgery.Validate(cookieToken, formToken) validates if pair of tokens is valid

You totally can repurpose those two methods and use formToken as headerToken and cookieToken as actual cookieToken. Then just call validate on both within attribute.

Another solution is to use JWT (check eg MembershipReboot implementation)

This link shows how to use built in anti-forgery tokens with ajax:

<script>
    @functions{
        public string TokenHeaderValue()
        {
            string cookieToken, formToken;
            AntiForgery.GetTokens(null, out cookieToken, out formToken);
            return cookieToken + ":" + formToken;                
        }
    }

    $.ajax("api/values", {
        type: "post",
        contentType: "application/json",
        data: {  }, // JSON data goes here
        dataType: "json",
        headers: {
            'RequestVerificationToken': '@TokenHeaderValue()'
        }
    });
</script>


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

    IEnumerable<string> tokenHeaders;
    if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
    {
        string[] tokens = tokenHeaders.First().Split(':');
        if (tokens.Length == 2)
        {
            cookieToken = tokens[0].Trim();
            formToken = tokens[1].Trim();
        }
    }
    AntiForgery.Validate(cookieToken, formToken);
}

Also take a look at this question AngularJS can’t find XSRF-TOKEN cookie

Leave a Comment