OdeToCode IC Logo

Combining HttpPost and ValidateAntiForgeryToken

Thursday, September 8, 2016

I’ve been kicking around the idea of combining [HttpPost] and [ValidateAntiForgeryToken] in an application using authentication cookies. Both attributes typically appear together to prevent cross-site request forgeries in MVC applications using cookie based authentication. The result looks like the following.

[HttpPostWithValidAntiForgeryToken]
public IActionResult Edit(Input model)
{
    // ... 
}

And the attribute definition is as follows.

public class HttpPostWithValidAntiForgeryToken
    : Attribute, IActionHttpMethodProvider, IFilterFactory
{
    private readonly HttpPostAttribute _postAttribute;
    private readonly ValidateAntiForgeryTokenAttribute _antiForgeryAttribute;

    public HttpPostWithValidAntiForgeryToken()
    {
        _postAttribute = new HttpPostAttribute();
        _antiForgeryAttribute = new ValidateAntiForgeryTokenAttribute();
    }

    public IEnumerable<string> HttpMethods => _postAttribute.HttpMethods;

    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
    {
        return _antiForgeryAttribute.CreateInstance(serviceProvider);
    }

    public bool IsReusable => _antiForgeryAttribute.IsReusable;
}

With the new attribute, a plain [HttpPost] should never appear in the application, and a unit test using reflection could enforce the rule.