Customize antiforgery failure response

iKingNinja 100 Reputation points
2024-11-21T11:56:42.16+00:00

I want to customize the response received by the client when CSRF token validation fails. I was looking at ASP.NET Core's source code and found the middleware I think is supposed to handle CSRF token validation.

By looking at it I found that it sets an IAntiForgeryValidationFeature, so I created a custom middleware to check if the feature is set and if it contains an error.

public class CustomAntiForgeryValidationResponseMiddleware(RequestDelegate next)
{
    public async Task InvokeAsync(HttpContext context)
    {
        IAntiforgeryValidationFeature? antiforgeryValidation = context.Features.Get<IAntiforgeryValidationFeature>();
        if (antiforgeryValidation is not null && !antiforgeryValidation.IsValid)
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsJsonAsync(new ProblemDetails()
            {
                Title = "Forbidden",
                Detail = "User is not allowed to perform this action",
                Status = 403,
                Extensions = new Dictionary<string, object?>()
                {
                    { "errors", new ApiError[] { new("Invalid or missing CSRF token") } }
                }
            });
        }
        await next(context);
    }
}

I then added it to the request pipeline in Program.cs before app.UseAuthentication():

app.UseMiddleware<CustomAntiForgeryValidationResponseMiddleware>();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

However antiforgeryValidation is always null even when the endpoint requires a CSRF token.

What am I doing wrong?

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,645 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 67,406 Reputation points
    2024-11-21T17:10:04.0966667+00:00

    your middleware is checking the results before the antiforgery middleware runs. make it the last middleware, or check after calling Next();
    note: I'm not sure controller continue processing the pipeline on an antiforgery validation error. so your middleware may not be called on error. if so, have it first and check after next call.


  2. iKingNinja 100 Reputation points
    2024-11-21T21:39:46.24+00:00

    Turns out the AntiforgeryMiddleware is not being invoked at all (probably because I am not using minimal APIs but rather MVC). I managed to fix this by creating a custom attribute and filter as the framework does and then globally registering the attribute.

    AutoValidateAntiforgeryTokenAttribute.cs

    AutoValidateAntiforgeryTokenAuthorizationFilter.cs


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.