Search code examples
c#asp.net-mvcangularjsasp.net-web-api2antiforgerytoken

antiforgeryToken to protect some actions on web api called from an angularjs app


I Have two web project in visualstudio.net 2013.

  • One project i a WebApi2 with controllers and actions (simple)
  • second project is a pure angularjs app with no MVC or WebApi (I started from an empty web project)

the angularjs application is calling service running on the webApi2 application.

I would like to know if it's possible to protect some actions of my controllers in my webapi2 application with an AntiforgeryToken. (antiforgeryToken attribute) I found some post on the web but they require to use AntiForgery.GetTokens in my angular app and Therefore, I have to install all the mvc and razor... nuget packages. (see this post : http://www.fredonism.com/archive/protect-your-web-api-from-csrf-attacks.aspx)

I would like to avoid this or is there a solution to use this antiforgerytoken with a minimal nuget packages installed ?

In other words : is it possible to protect some of my webapi controller actions with antiforgery token without using the MVC stuff.

regards


Solution

  • Even though it's too late for this question, this will benefit others perhaps in the future.

    First create a middleware to handle the requests in web api project.

    public class AntiForgeryMiddleware
        {
            private readonly RequestDelegate next;
            private readonly string requestTokenCookieName;
            private readonly string[] httpVerbs = new string[] { "GET", "HEAD", "OPTIONS", "TRACE", "POST" };
    
            public AntiForgeryMiddleware(RequestDelegate next, string requestTokenCookieName)
            {
                this.next = next;
                this.requestTokenCookieName = requestTokenCookieName;
            }
    
            public async Task Invoke(HttpContext context, IAntiforgery antiforgery)
            {
    
                string path = context.Request.Path.Value;
    
                if (path != null && path.ToLower().Contains("yourMethodThatGeneratesTheToken"))
                {
                    if (httpVerbs.Contains(context.Request.Method, StringComparer.OrdinalIgnoreCase))
                    {
                        var tokens = antiforgery.GetAndStoreTokens(context);
    
                        context.Response.Cookies.Append(requestTokenCookieName, tokens.RequestToken, new CookieOptions()
                        {
                            HttpOnly = false
                        });
    
    
                    } 
                }
    
                context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    
                await next.Invoke(context);
            }
        }
    

    Add the middleware in your Configure method of Startup.cs

    app.UseAntiforgeryTokenMiddleware("X-XSRF-TOKEN");

    In your angular interceptor, you may set the header as follows, by taking the cookie.

    var xsrfToken = this.cookieService.get("X-XSRF-TOKEN"); req.headers.set('X-XSRF-TOKEN', xsrfToken)

    in order to save the cookie you'll need to add req = req.clone({ withCredentials: true }); at the top of the interceptor.