AnointedAutomation.APIMiddlewares 1.0.9

dotnet add package AnointedAutomation.APIMiddlewares --version 1.0.9
                    
NuGet\Install-Package AnointedAutomation.APIMiddlewares -Version 1.0.9
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AnointedAutomation.APIMiddlewares" Version="1.0.9" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AnointedAutomation.APIMiddlewares" Version="1.0.9" />
                    
Directory.Packages.props
<PackageReference Include="AnointedAutomation.APIMiddlewares" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AnointedAutomation.APIMiddlewares --version 1.0.9
                    
#r "nuget: AnointedAutomation.APIMiddlewares, 1.0.9"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AnointedAutomation.APIMiddlewares@1.0.9
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AnointedAutomation.APIMiddlewares&version=1.0.9
                    
Install as a Cake Addin
#tool nuget:?package=AnointedAutomation.APIMiddlewares&version=1.0.9
                    
Install as a Cake Tool

AnointedAutomation.APIMiddlewares

Jesus is King ✝️

ASP.NET Core middleware and filters for protecting small APIs: API key authentication, an in memory IP blacklist, automatic banning of clients that probe for endpoints that do not exist, and optional garbage collection when the API has been idle.

NuGet Downloads

Installation

dotnet add package AnointedAutomation.APIMiddlewares

Quick start

using System;
using AnointedAutomation.APIMiddleware;
using Microsoft.AspNetCore.Builder;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
WebApplication app = builder.Build();

// Reject blacklisted IPs with 403 before anything else runs.
app.UseMiddleware<IPBlacklistMiddleware>();

// Count 404/401/403 responses per IP and ban repeat offenders.
app.UseMiddleware<InvalidEndpointTrackerMiddleware>();

// Require an API key header on everything under /api (constant-time comparison).
app.UseMiddleware<ApiKeyAuthMiddleware>(
    "X-Api-Key",                                          // header name
    Environment.GetEnvironmentVariable("MY_API_KEY"),     // expected key
    "/api");                                              // protected path prefix

// Track endpoint hits; run a GC when every endpoint has been idle for 10 minutes.
app.UseMiddleware<EndpointAccessMiddleware>((TimeSpan?)TimeSpan.FromMinutes(10), true);

app.MapControllers();
app.Run();

Note the namespace: the code lives in AnointedAutomation.APIMiddleware (singular), even though the package id is AnointedAutomation.APIMiddlewares.

API overview

Middleware (AnointedAutomation.APIMiddleware)

Type What it does
ApiKeyAuthMiddleware Constructor (RequestDelegate next, string headerName, string expectedKey, string protectedPathPrefix). Requests whose path starts with the prefix must send the header with the exact key or get 401. Uses CryptographicOperations.FixedTimeEquals. Also exposes static bool IsAuthorized(string presentedKey, byte[] expectedKey). The prefix must start with /.
IPBlacklistMiddleware Returns 403 for any client IP in IPBlacklist. Also owns the shared middleware log buffer: static AddLog(LogMessage), static GetLogs(), static ClearLogs(), and the static events LogAdded and LogCleared.
InvalidEndpointTrackerMiddleware Returns 403 for blacklisted IPs. After the rest of the pipeline runs, records a failed attempt for a 404 with an empty body (except /), a 401 or a 403. An IP is banned after 10 failed attempts, or immediately if it requests a path ending in .env. Attempt counts and logs reset every 24 hours. static ClearFailedAttempts() resets counts.
AttemptInfo Attempt record for one IP: int Count, HashSet<string> Paths.
EndpointAccessMiddleware Constructor (RequestDelegate next, TimeSpan? timeout, bool cleanMem = false). Records the last access time per path. When cleanMem is true, a one minute timer runs AnointedAutomation.Optimization.Memory.GarbageCollection.PerformGarbageCollection once every endpoint has been idle longer than timeout. static bool HasBeenHitRecently(string path) reports whether a path was hit in the last 5 minutes.

Filters (AnointedAutomation.APIMiddleware.Filters)

Type What it does
APIKeyAttribute [APIKey] action filter for controllers or actions. Reads the header name from the API_KEY_NAME environment variable and the expected key from API_KEY; a missing or wrong key returns 401 and logs a warning with the client IP.

Objects (AnointedAutomation.APIMiddleware.Objects)

Type What it does
IPBlacklist Static in memory blacklist: AddBannedIP(string ip, string reason), RemoveBannedIP(string ip), IsIPBlocked(string ipAddress), GetBlockReason(string ipAddress), ClearBlacklist(), and the events IPBanned (EventHandler<BannedIP>) and IPUnbanned (EventHandler<string>).
BannedIP _id, Ipv4, Ipv6, Reason. Handy as a persistence shape for bans.

Utility (AnointedAutomation.APIMiddleware.Utility)

Type What it does
APIUtility GetClientPublicIPAddress(HttpContext) and GetClientPublicIPAddress(ActionExecutingContext). Uses the first X-Forwarded-For value, then RemoteIpAddress. Returns 198.51.100.255 for ::1 or when no IP is available, and logs why.

Using the [APIKey] filter

using AnointedAutomation.APIMiddleware.Filters;
using Microsoft.AspNetCore.Mvc;

[APIKey]
[ApiController]
[Route("[controller]")]
public class SecureController : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok("Secure data");
}

Required environment variables:

API_KEY_NAME=X-Api-Key
API_KEY=your-secret-key

ApiKeyAuthMiddleware is the newer option: it takes its values as arguments instead of reading environment variables, and compares keys in constant time.

Persisting and observing bans

The blacklist is in memory and is lost on restart. Use the events to persist bans and reload them at startup:

using System;
using AnointedAutomation.APIMiddleware;
using AnointedAutomation.APIMiddleware.Objects;
using AnointedAutomation.Optimization.Logging;

IPBlacklist.IPBanned += (sender, banned) =>
    Console.WriteLine($"Banned {banned.Ipv4}: {banned.Reason}");

IPBlacklist.AddBannedIP("203.0.113.7", "Loaded from database");

IPBlacklistMiddleware.LogAdded += (sender, e) =>
    Console.WriteLine($"[{e.log.messageType}] {e.log.message}");

IPBlacklistMiddleware.AddLog(LogMessage.Warning("Suspicious activity detected."));

Note that IPBlacklistMiddleware.ClearLogs() and IPBlacklist.ClearBlacklist() also remove every event subscriber, and InvalidEndpointTrackerMiddleware calls ClearLogs() during its 24 hour reset, so resubscribe to IPBlacklistMiddleware.LogAdded if you rely on it long term.

Notes

  • The client IP comes from X-Forwarded-For when present. Only trust it behind a reverse proxy that sets it.
  • All state (blacklist, attempt counts, logs) is static and per process.

License

MIT. See LICENSE.

Support This Project

This library is free and open source. The best way to support the work is to shop with us:

Found a bug or have a request? Open an issue at https://github.com/AnointedAutomation/AnointedAutomation/issues.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.9 93 10/26/2026
1.0.8 449 10/1/2026
1.0.7 127 10/1/2026
1.0.6 236 9/25/2026
1.0.5 413 8/23/2026
1.0.4 728 6/23/2026
1.0.3 190 6/20/2026
1.0.2 326 5/30/2026
1.0.0 649 3/15/2026
0.0.18 231 3/13/2026
0.0.17 142 3/11/2026
0.0.16 534 2/20/2026
0.0.15 199 2/17/2026