Recently I wanted to create a custom authentication, to authorize by ApiKey and ApiSecret in the header. To create such a middleware to affect the entire services of the system I created the following:
using System; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; public class ApiKeyMiddleware { private readonly RequestDelegate _next; private readonly IConfiguration _config; private readonly ILogger _logger; public ApiKeyMiddleware(RequestDelegate next, IConfiguration config, ILogger<ApiKeyMiddleware> logger) { _next = next; _config = config; _logger = logger; } public async Task InvokeAsync(HttpContext context) { if (!context.Request.Headers.ContainsKey("X-Api-Key") || !context.Request.Headers.ContainsKey("X-Api-Secret")) { _logger.LogWarning("Missing API key or secret."); context.Response.StatusCode = 401; await context.Response.WriteAsync("Unauthorized"); return; } var apiKey = context.Request.Headers["X-Api-Key"].FirstOrDefault(); var apiSecret = context.Request.Headers["X-Api-Secret"].FirstOrDefault(); if (!IsAuthorized(apiKey, apiSecret)) { _logger.LogWarning($"Invalid API key or secret: {apiKey}"); context.Response.StatusCode = 401; await context.Response.WriteAsync("Unauthorized"); return; } await _next(context); } private bool IsAuthorized(string apiKey, string apiSecret) { var storedApiKey = _config.GetValue<string>("ApiKey"); var storedApiSecret = _config.GetValue<string>("ApiSecret"); if (apiKey == storedApiKey && apiSecret == storedApiSecret) { return true; } return false; } }
In the InvokeAsync method of this middleware, I check if the request headers contain the X-Api-Key and X-Api-Secret headers. If they are missing, I return a 401 Unauthorized response. If they are present, I check if the provided key and secret match the ones stored in the configuration. If they match, I continue with the request processing. If they don't match, I return a 401 Unauthorized response. Next, I added this middleware to the pipeline in the Configure method of Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ... app.UseMiddleware<ApiKeyMiddleware>(); // ... }
Finally, I added the ApiKey and ApiSecret configuration values to the appsettings.json file:
{ "ApiKey": "your-api-key", "ApiSecret": "your-api-secret" }
This was just a simple form of what I created for the project as it has more challenges. Hope it helps!