I have a Web API project that has a number of endpoints that are protected using an API key. To achieve this I have written some middleware to handle checking the header for the API key and validating it. This middleware is configured in the Startup.cs
app.UseMiddleware<ApiKeyMiddleware>();
This works perfectly, however I now have the requirement to have one endpoint that does not require any authorisation so it can be viewed in browser. I was hoping this would be done by using the AllowAnonymous attribute, however the middleware still checks for the API key.
I can achieve what I want by removing the middleware and making the API key check into an attribute, but is there a better way to do this?
EDIT:
This is the API key middleware implementation.
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private const string API_KEY_HEADER = "z-api-key";
public ApiKeyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
if (!context.Request.Headers.TryGetValue(API_KEY_HEADER, out var extractedApiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync($"Api Key was not found in request. Please pass key in {API_KEY_HEADEr} header.");
return;
}
var appSettings = context.RequestServices.GetRequiredService<IConfiguration>();
var validApiKey = appSettings.GetValue<string>(API_KEY_HEADER);
if (validApiKey != extractedApiKey)
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Invalid api key.");
return;
}
await _next(context);
}
}
Bearertoken, you can use the built-inAuthorizeattribute on the controller(s) and useAllowAnonymousto exempt specific actionscontext.Request.Path)