Search code examples
c#asp.net-coreauthenticationcookiesasp.net-core-middleware

Stop request in CookieAuthenticationEvents.OnValidatePrincipal after response body has been written to


In OnValidatePrincipal, I have the following code:

async (context) =>
{
    await context.HttpContext.SignOutAsync();
    context.Principal = null;
    context.Response.StatusCode = 452;
    await context.Response.WriteAsJsonAsync(new { Description = "Sample description"});
    await context.Response.Body.FlushAsync();
}

For some reason though, the request continues to where it originally pointed to, executing the action and the code behind it.

I'm not sure if this is a bug or not, but the response has been written - it seems pointless to go forward and execute the action/endpoint the request was originally pointing to. Is there a way to stop this?

Even though the action being executed returns a different response, ASP.NET Core correctly returns the response I've written inside OnValidatePrincipal, probably due to flushing it, locking the stream from further writing?


Solution

  • I've fixed this via the use of a custom-made middleware:

    /// <summary>
    /// A middleware that short-circuits the request's pipeline, if a response has already been started.
    /// </summary>
    public class EnsureResponseNotStartedMiddleware
    {
        private readonly RequestDelegate _nextMiddleware;
    
        public EnsureResponseNotStartedMiddleware(RequestDelegate nextMiddleware)
        {
            _nextMiddleware = nextMiddleware;
        }
    
        public Task InvokeAsync(HttpContext context)
        {
            if (!context.Response.HasStarted)
            {
                return _nextMiddleware(context);
            }
    
            return Task.CompletedTask;
        }
    }