https://blog.mariusschulz.com/2017/06/11/global-antiforgery-token-validation-in-asp-net-core
In this blog post, I want to share a small piece of ASP.NET Core middleware that implements antiforgery token validation for all POST requests. If you're not yet familiar with cross-site request forgery (CSRF/XSRF) or antiforgery tokens as a defense mechanism, I recommend you read the following articles first: Before we take a look at the middleware itself, let's recap how we can secure each ASP.NET MVC controller action manually, one by one. To secure a controller action against CSRF, we can decorate it with the Within our Razor views, we can use the This approach works, but it has a drawback: We have to manually decorate every controller action that deals with POST requests with the Let's see how we can implement the antiforgery token validation in a single place so that it "just works" for all POST requests. Here's the middleware in its entirety: The idea is that we check whether the current HTTP request is a POST request, and if it is, we validate that it was sent with a correct antiforgery token. This validation functionality is provided by the If the request does not contain a valid antiforgery token, the Of course, simply creating the middleware class is not enough. We have to instantiate it and add it to the request pipeline to take effect: Here, I've written a simple extension method that follows the And there we go! We now automatically validate antiforgery tokens for each POST request.#The Manual Approach
[ValidateAntiForgeryToken]
attribute. The action will then only execute if the HTTP request contains a valid antiforgery token:[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Logout()
{
// ...
return View();
}
@Html.AntiForgeryToken()
method to have the framework generate a hidden <input>
holding the expected antiforgery token:<form action="..." method="POST">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
[ValidateAntiForgeryToken]
attribute, which is a little cumbersome. More importantly, though, it's quite easy to forget to add the attribute, which makes the corresponding controller action vulnerable to CSRF attacks.#Using Middleware to Validate Antiforgery Tokens
using System.Threading.Tasks;
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Http;
public class ValidateAntiForgeryTokenMiddleware
{
private readonly RequestDelegate _next;
private readonly IAntiforgery _antiforgery;
public ValidateAntiForgeryTokenMiddleware(RequestDelegate next, IAntiforgery antiforgery)
{
_next = next;
_antiforgery = antiforgery;
}
public async Task Invoke(HttpContext context)
{
if (HttpMethods.IsPost(context.Request.Method))
{
await _antiforgery.ValidateRequestAsync(context);
}
await _next(context);
}
}
IAntiforgery
service, which we resolve via the constructor of the middleware.ValidateRequestAsync
method will throw an AntiforgeryValidationException
. In this case, _next(context)
will not be called and the rest of the request pipeline won't be executed. It is then up to some error handling middleware to display an error to the user.#Adding Our Middleware to the Request Pipeline
public void Configure(IApplicationBuilder app)
{
// ...
app.UseAntiforgeryTokens();
// ...
}
Use...
naming scheme which is common in ASP.NET Core:using Microsoft.AspNetCore.Builder;
public static class ApplicationBuilderExtensions
{
public static IApplicationBuilder UseAntiforgeryTokens(this IApplicationBuilder app)
{
return app.UseMiddleware<ValidateAntiForgeryTokenMiddleware>();
}
}
#Further Reading