Skip to content

API Key Auth

Simple API Key authentication is a great option when building public facing APIs without strict security requirements, but you would rather not leave open. Think syncs, long running jobs or other non-critical operations.

Configuration

This example stores the ApiKey in the appsettings.json file. You can also store it in a database, environment variable, or any other configuration source.

json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ApiKey": "ThisIsMySecretKey",
  // ...
}

Filter

The logic for the api key authentication is a simple Authorization filter. It checks the ApiKey header against the configured value.

Start by storing the header name in a constants file or similar:

csharp
namespace ApiKeyAuthDemo.Core
{
    public static class Constants
    {
        public const string API_KEY_HEADER_NAME = "X-API-KEY";
    }
}

Then create the filter:

csharp
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace ApiKeyAuthDemo.Core.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class ApiKeyAuthorizeAttribute() : Attribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            // Get the API key from the request headers
            string? apiKeyValue = context.HttpContext.Request.Headers[Constants.API_KEY_HEADER_NAME];

            // Get the API key from the configuration
            IConfiguration configuration = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
            string? apiKey = configuration.GetValue<string>("ApiKey");

            // Check if the API key is valid and set
            if (apiKeyValue == null || apiKeyValue != apiKey)
            {
                context.Result = new UnauthorizedResult();
            }
        }
    }
}

Usage

See below for example usage (on the second GET method):

csharp
using ApiKeyAuthDemo.Core.Filters;
using Microsoft.AspNetCore.Mvc;

namespace ApiKeyAuthDemo.Controllers;

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }

    [ApiKeyAuthorize]
    [HttpGet("auth")]
    public IEnumerable<WeatherForecast> GetAuth()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }
}