Audis.Authentication.Hmac
2.0.0
dotnet add package Audis.Authentication.Hmac --version 2.0.0
NuGet\Install-Package Audis.Authentication.Hmac -Version 2.0.0
<PackageReference Include="Audis.Authentication.Hmac" Version="2.0.0" />
<PackageVersion Include="Audis.Authentication.Hmac" Version="2.0.0" />
<PackageReference Include="Audis.Authentication.Hmac" />
paket add Audis.Authentication.Hmac --version 2.0.0
#r "nuget: Audis.Authentication.Hmac, 2.0.0"
#:package Audis.Authentication.Hmac@2.0.0
#addin nuget:?package=Audis.Authentication.Hmac&version=2.0.0
#tool nuget:?package=Audis.Authentication.Hmac&version=2.0.0
Audis.Authentication.Hmac
HMAC-Mechanismus für Audis.Authentication auf Basis von softaware.Authentication.Hmac: Inbound-Scheme mit Replay-Schutz über IDistributedCache, Algorithmus-Allowlist und robuster Header-Prüfung sowie Signatur ausgehender Requests. Policies, Modi, Rechte pro Client und Outbound-Credentials sind im Paket Audis.Authentication beschrieben.
Verwendung
HMAC ist der interne Standard für Service-to-Service-Aufrufe. Das Paket nutzt softaware.Authentication.Hmac unverändert als Abhängigkeit und ist header-kompatibel zu bestehenden Clients und Servern dieser Bibliothek.
// Inbound und Outbound
builder.Services.AddAudisAuthentication(builder.Configuration)
.AddHmac()
.AddApiKey();
// Erforderlich für Enforce-Policies mit Hmac: gemeinsamer Distributed Cache für den Replay-Schutz
builder.Services.AddStackExchangeRedisCache(options => options.Configuration = "...");
// Outbound: Credential pro Request (wie bei ApiKey) ...
services.AddHttpClient<IEndpointNotifier, HttpEndpointNotifier>()
.AddAudisOutboundAuthentication();
request.Options.Set(AudisAuthRequestOptions.Credential, "trust");
// ... oder ein festes Credential für alle Requests eines Clients (Mechanismus per Konfiguration umstellbar)
services.AddHttpClient<ITrustClient, TrustClient>()
.AddAudisOutboundAuthentication("trust");
// ... oder ausdrücklich HMAC
services.AddHttpClient<ICobraClient, CobraClient>()
.AddAudisHmacAuthentication("cobra");
Konfiguration:
"Authentication": {
"Inbound": {
"Hmac": {
"Clients": [ { "AppId": "cobra-adapter", "ApiKeys": [ "<neu, Base64>", "<alt, Base64>" ], "Policies": [ "Webhook" ], "Tenants": [ "tenant-a" ] } ],
"MaxRequestAgeInSeconds": 300, // Default 300, erlaubt 1..86400
"TrustProxy": false, // X-Forwarded-Proto für die signierte URI verwenden
"AllowLegacyHeaderFormat": false, // 4-teiliges Legacy-Format (MD5-Body-Hash), Default false
"AllowProcessLocalNonceStore": false // nur Single-Replica/Entwicklung: Enforce ohne geteilten Cache erlauben, Default false
},
"Policies": {
"ServiceToService": { "Schemes": [ "Hmac" ], "Mode": "Audit" },
"Webhook": { "Schemes": [ "Hmac", "ApiKey" ], "Mode": "Audit" }
}
},
"Outbound": {
"Credentials": {
"trust": { "Type": "Hmac", "AppId": "audis-web", "ApiKey": "<Base64>", "AllowedOrigins": [ "https://trust.example.org" ] },
"cobra": { "Type": "Hmac", "AppId": "audis-web", "ApiKey": "<Base64>", "HmacHashingMethod": "HMACSHA512", "RequestBodyHashingMethod": "SHA512", "AllowedOrigins": [ "https://cobra.example.org" ] }
}
}
}
Ablauf beim Empfang (Scheme AudisHmac):
- Ohne
Authorization: Hmac ...-Header liefert das Scheme kein Ergebnis, andere Schemes der Policy (z.B.ApiKey) können den Request authentifizieren. - Der Header wird vorab geprüft (Format, Algorithmen, Base64-Signatur, Timestamp als Unix-Sekunden in kanonischer Form ohne führende Nullen oder Vorzeichen, Nonce aus genau 32 Hex-Zeichen wie beim upstream-Client). Ungültige Header führen zu
401bzw. imAudit-Modus zu einer Warnung, nie zu einem500. - Das upstream-Scheme prüft AppId, Signatur (alle Keys des Clients, Rotation ohne Neustart), Zeitfenster
MaxRequestAgeInSecondsund die Nonce pro Replica. - Die Nonce wird zusätzlich im
INonceStoregeprüft und gespeichert. Ist sie bereits bekannt, wird der Request abgewiesen (Replay). - Der Principal enthält
audis:service= AppId (zusätzlichNameIdentifierundName) sowie diePolicies/Tenantsdes Clients (audis:policy,audis:tenant, siehe Client-Rechte beiAudis.Authentication). Fehlt der Client nach einem Reload, wird der Request abgewiesen (fail closed). - Wird die HMAC-Konfiguration während der Prüfung neu geladen, wird der Request abgewiesen (fail closed): Der Principal enthält nie Rechte aus einer Konfiguration, die nicht mehr gilt. Der Client wiederholt den Request mit neuer Nonce.
Hinweise:
- Header-Format:
Hmac {HmacHashingMethod}:{RequestBodyHashingMethod}:{AppId}:{Base64-Signatur}:{Nonce}:{Unix-Sekunden}. Die Keys sind Base64-kodiert und müssen dekodiert mindestens 32 Bytes (256 Bit) lang sein, wie sie der Key-Generator vonsoftaware.Authentication.Hmacerzeugt (z.B.Convert.ToBase64String(RandomNumberGenerator.GetBytes(32))). Kürzere Keys verhindern den Start. Die AppId darf kein:enthalten. - Groß-/Kleinschreibung der URI: upstream (
softaware.Authentication.Hmac) signiert die URI in Kleinbuchstaben. Zwei URIs, die sich nur in der Groß-/Kleinschreibung von Pfad oder Query unterscheiden, haben daher dieselbe Signatur. Das ist für die Kompatibilität mit bestehenden Clients beibehalten; Schutz bieten TLS (ein Request kann unterwegs nicht verändert werden) und die Nonce (jeder signierte Request wird nur einmal akzeptiert). Endpunkte, bei denen die Schreibweise von Pfad oder Query die Bedeutung ändert, sollten das berücksichtigen. - Prozent-kodierte Zeichen im Pfad: Der Client signiert die URI so, wie sie gesendet wird (
Uri.AbsoluteUri), upstream prüft auf dem Server den dekodierten Pfad. Prozent-kodierte reservierte Zeichen wie%3A(:),%40(@),%3D(=),%2C(,) oder%24($) im Pfad ergeben daher auf beiden Seiten unterschiedliche Signaturen, der Request wird abgewiesen (fail closed). Das betrifft z.B. AUDIS-IDs wiecatalog:12, wenn sie mitUri.EscapeDataStringin den Pfad gesetzt werden. Abhilfe: solche Werte unkodiert in den Pfad setzen (:ist im Pfad erlaubt) oder als Query-Parameter bzw. im Body übertragen.%2F, Leerzeichen und Nicht-ASCII-Zeichen sind nicht betroffen. - Kultur: upstream wandelt die URI mit der aktuellen Kultur in Kleinbuchstaben um. Laufen Client und Server mit unterschiedlichen Kulturen, deren Kleinschreibung abweicht (z.B.
tr-TRbeimI), schlägt die Prüfung für solche Pfade fehl. Dienste sollten mit invarianter oder gleicher Kultur laufen. - Algorithmen: Erlaubt sind
HMACSHA256/HMACSHA384/HMACSHA512und als Body-HashSHA256/SHA384/SHA512. MD5 und SHA1 werden eingehend und ausgehend abgewiesen. Das 4-teilige Legacy-Format impliziert einen MD5-Body-Hash und wird nur mitAllowLegacyHeaderFormat: trueakzeptiert. - Replay-Schutz: Der Default-
INonceStorenutzt einen registriertenIDistributedCache(Keyaudis:hmac:nonce:{AppId}:{Nonce}). Die TTL beträgt2 × 86400 + 60Sekunden (gut 2 Tage): upstream akzeptiert Timestamps bisMaxRequestAgeInSecondsin der Vergangenheit und in der Zukunft, die 60 Sekunden decken Uhrenabweichungen zwischen Replicas ab. Die TTL richtet sich nach dem größten zulässigen Fenster (86400 s), nicht nach dem konfigurierten: Sonst könnte ein verbrauchter Request nach einem Reload mit größeremMaxRequestAgeInSeconds(oder auf einer anderen Replica mit größerem Fenster) erneut akzeptiert werden, sobald sein Eintrag abgelaufen ist. Der Cache muss daher pro akzeptiertem HMAC-Request einen kleinen Eintrag für diese Dauer halten.- Ohne registrierten
IDistributedCacheoder mitAddDistributedMemoryCache()gilt der Replay-Schutz nur pro Replica: ein abgefangener Request kann innerhalb des Zeitfensters einmal pro Replica wiederholt werden.- Ist
Hmacin einer Policy mitEnforceaktiv, schlägt die Startup-Validierung fehl (fail closed). Abhilfe: einen geteiltenIDistributedCache(z.B. Redis) oder einen eigenenINonceStoreregistrieren. Nur für eine einzelne Replica oder die Entwicklung kann das mitAllowProcessLocalNonceStore: truebewusst erlaubt werden. - Bei
Audit(und beiEnforcemitAllowProcessLocalNonceStore: true) wird beim Start eine Warnung geloggt (EventId 2001 bzw. 2002).
- Ist
IDistributedCachehat kein atomares „Add if not exists“. Innerhalb einer Replica werden gleichzeitige Requests mit derselben Nonce serialisiert. Zwischen Replicas bleibt ein kleines Restrisiko: zwei gleichzeitige Requests mit derselben Nonce können innerhalb der Cache-Roundtrip-Zeit auf unterschiedlichen Replicas beide akzeptiert werden. Wer das ausschließen muss, registriert eine eigeneINonceStore-Implementierung (z.B. RedisSET NX).- Ist der Cache nicht erreichbar, wird der Request abgewiesen (fail closed) und ein Fehler geloggt.
- Ohne registrierten
- Validierung (Start und Reload): Clients ohne AppId oder Keys, Keys ohne gültiges Base64 oder kürzer als 32 Bytes, doppelte AppIds, derselbe Key bei mehreren AppIds (die Meldung nennt nur die AppIds), unbekannte
Policiesoder ungültigeTenantseines Clients, ungültigesMaxRequestAgeInSeconds, eine aktive Policy mitHmacohne Clients, eineEnforce-Policy mitHmacohne geteilten Replay-Schutz (siehe oben) sowie ausgehendeHmac-Credentials ohne AppId, mit ungültigem Key, schwachem Algorithmus oder ohne gültigeAllowedOriginsverhindern den Start. Bei einem Reload (z.B. Umstellung einer Policy vonApiKeyaufHmac) werden dieselben Regeln geprüft, auch für HMAC-Clients, die im selben Reload hinzukommen: Ein ungültiger Reload wird nicht übernommen, die zuletzt gültigen Policies und Credentials bleiben aktiv. Requests an Origins außerhalb vonAllowedOriginswerden nicht signiert und nicht gesendet (auch mitAddAudisHmacAuthentication). Fehlermeldungen enthalten nie Keys. - Reverse Proxy: Die Signatur umfasst Methode und absolute URI. Werden Host oder Pfad durch einen Proxy umgeschrieben, schlägt die Prüfung fehl.
TrustProxyübernimmt nur das Schema ausX-Forwarded-Proto. IMemoryCache: Upstream speichert seine Nonces im registriertenIMemoryCacheohneSize. Setzt der HostMemoryCacheOptions.SizeLimit, schlägt die upstream-Prüfung fehl: Der Request wird nicht authentifiziert (401beiEnforce, Warnung beiAudit, nie500). Beim Start wird dann eine Warnung geloggt (EventId 2005). Ausnahmen von upstream werden nur mit ihrem Typ geloggt (EventId 2004).- Rate Limiting: upstream merkt sich die Nonce jedes Requests mit gültigem Header-Format und aktuellem Timestamp im
IMemoryCache, bevor die Signatur geprüft wird. Die AppId steht im Klartext im Header. Wer sie kennt, kann daher mit ungültigen Signaturen den Speicher einer Replica fürMaxRequestAgeInSecondsfüllen. HMAC-Endpunkte, die aus nicht vertrauenswürdigen Netzen erreichbar sind, sollten ein Rate Limiting haben (z.B. ASP.NET Core Rate Limiting, Reverse Proxy oder Gateway). - Größe des Replay-Caches: Pro akzeptiertem Request bleibt ein Eintrag gut 2 Tage im
IDistributedCache(siehe Replay-Schutz). Bei z.B. 50 Requests pro Sekunde sind das rund 8,6 Mio. Einträge; der Cache (z.B. Redis) muss dafür dimensioniert sein. - Große Bodies: Für die Signatur wird der Body ausgehender Requests gepuffert und von upstream noch einmal als Byte-Array gelesen, große Uploads belegen dabei etwa die doppelte Größe im Speicher.
- Client-Registrierung:
AddAudisHmacAuthentication()enthältAddAudisOutboundAuthentication(). Ein zusätzlicher Aufruf (davor oder danach) fügt keinen zweiten Handler hinzu, jeder Request wird genau einmal signiert. Wie dort werden Redirects (3xx) nicht automatisch verfolgt. Ein zweiter Aufruf mit einem anderen Credential-Namen führt beim Erzeugen des Clients zu einerInvalidOperationException. - Retries: Jeder Versuch wird neu signiert (neue Nonce und neuer Timestamp), sofern der Retry-Handler vor
AddAudisOutboundAuthentication()bzw.AddAudisHmacAuthentication()registriert ist. Bei mehreren Aufrufen zählt der letzte: Der Authentifizierungs-Handler steht an dessen Position, ein dazwischen registrierter Retry-Handler signiert also jeden Versuch neu. - Upstream-Version:
softaware.Authentication.Hmac.AspNetCoreund.Clientsind exakt gepinnt, weil das Header-Format im Wrapper selbst geparst wird. Ein Update erfordert eine bewusste Anpassung, die Kompatibilitätstests sichern das Format ab.
Lizenz
MIT, © softaware gmbh.
| Product | Versions 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. |
-
net10.0
- Audis.Authentication (>= 2.0.0)
- softaware.Authentication.Hmac.AspNetCore (= 5.1.0)
- softaware.Authentication.Hmac.Client (= 2.0.1)
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 |
|---|---|---|
| 2.0.0 | 81 | 11/4/2026 |