Web API and ValidateAntiForgeryToken

ScottS picture ScottS · Jul 13, 2012 · Viewed 56.2k times · Source

We have some existing MVC web services that are called AJAX style from web pages. These services make use of the ValidateAntiForgeryToken attribute to help prevent request forgeries.

We are looking to migrate these services to Web API, but there appears to be no equivalent anti-forgery functionality.

Am I missing something? Is there a different approach to addressing request forgeries with Web API?

Answer

Darin Dimitrov picture Darin Dimitrov · Jul 14, 2012

You could implement such authorization attribute:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class ValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
    public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    {
        try
        {
            AntiForgery.Validate();
        }
        catch
        {
            actionContext.Response = new HttpResponseMessage 
            { 
                StatusCode = HttpStatusCode.Forbidden, 
                RequestMessage = actionContext.ControllerContext.Request 
            };
            return FromResult(actionContext.Response);
        }
        return continuation();
    }

    private Task<HttpResponseMessage> FromResult(HttpResponseMessage result)
    {
        var source = new TaskCompletionSource<HttpResponseMessage>();
        source.SetResult(result);
        return source.Task;
    }
}

and then decorate your API actions with it:

[ValidateAntiForgeryToken]
public HttpResponseMessage Post()
{
    // some work
    return Request.CreateResponse(HttpStatusCode.Accepted);
}