Search code examples
.net-coreswaggermiddleware

Swashbuckle blocked by middleware authentication


I'm creating a minimal API in dotnet 6. I have the default implementation of Swagger/Swashbuckle and everything was fine until I added a simple, custom authentication middleware (see code below).

The problem is, the middleware runs against /swagger/index.html which doesn't contain the API Key in the header and returns a 400 error (per the first if statement below). How can I fix this?

Program.cs

app.UseMiddleware<Auth>();

Auth.cs

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        if (!context.Request.Headers.ContainsKey("ApiKey"))
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;

            await context.Response.WriteAsync("No ApiKey provided in headers");
        }

        if (!Guid.TryParse(context.Request.Headers["ApiKey"], out var apiKey))
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;

            await context.Response.WriteAsync("Unable to parse the ApiKey");
        }

        try
        {
            /* Look in DB for API Key yada yada yada */
        }
        catch
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;

            await context.Response.WriteAsync("Unauthorized");
        }

        await next(context);
    }

Solution

  • you can exclude the path which you don't want to check for auth middleware.

    something like this.

        public async Task InvokeAsync(HttpContext context)
        {
            if(!context.Request.Path.StartsWithSegments("/swagger"))
            {
                  //put your code here for checking API key in header.
            }
         }
    

    also you need to return once you set the response otherwise you will get another exception.

    here is the working code:

        public async Task InvokeAsync(HttpContext context)
        {
            if(!context.Request.Path.StartsWithSegments("/swagger"))
            {
                if (!context.Request.Headers.ContainsKey("ApiKey"))
                {
                    context.Response.StatusCode = StatusCodes.Status400BadRequest;
    
                    await context.Response.WriteAsync("No ApiKey provided in headers");
                    return;
                }
    
                if (!Guid.TryParse(context.Request.Headers["ApiKey"], out var apiKey))
                {
                    context.Response.StatusCode = StatusCodes.Status400BadRequest;
    
                    await context.Response.WriteAsync("Unable to parse the ApiKey");
                    return;
                }
    
                try
                {
                    /* Look in DB for API Key yada yada yada */
                }
                catch
                {
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
    
                    await context.Response.WriteAsync("Unauthorized");
                    return;
                }
            }
    
            await this._next(context);
        }
    }