und wann welches Verfahren wirklich passt
Die Wahl des falschen Authentifizierungsverfahrens kostet nicht nur Sicherheit, sondern auch Entwicklerzeit bei jeder Integration. API-Keys, Bearer Token, OAuth2 und HMAC Signed Requests lösen unterschiedliche Probleme – und wer den Unterschied kennt, trifft die richtige Entscheidung vor dem ersten Commit.
Inhaltsverzeichnis
- 1. Das Authentifizierungsproblem bei APIs
- 2. API-Keys: einfach, aber begrenzt
- 3. Bearer Token und JWT: zustandslose Authentifizierung
- 4. OAuth2 Flows: welcher wofür
- 5. Authorization Code + PKCE: der sichere Browser-Flow
- 6. HMAC Signed Requests: Integrität und Replay-Schutz
- 7. mTLS: gegenseitige Zertifikatsauthentifizierung
- 8. Token-Sicherheit: Rotation, Revocation und Scope
- 9. Verfahren im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Das Authentifizierungsproblem bei APIs
API-Authentifizierung löst ein fundamentales Problem: Wie stellt eine API sicher, dass ein eingehender Request von einem berechtigten Client stammt – und nicht von einem Angreifer, der eine Verbindung abgehört, einen Token gestohlen oder einen Request replayed hat? Die Antwort hängt stark vom Anwendungsfall ab. Eine interne Microservice-Kommunikation hat andere Anforderungen als eine öffentliche Developer-API, und ein SPA, das auf Nutzerdaten zugreift, hat andere Anforderungen als ein Backend-to-Backend-Webhook.
Die häufigste Fehlentscheidung: API-Keys für alle Szenarien einsetzen, weil sie am einfachsten zu implementieren sind. API-Keys haben keine eingebaute Expiry, keine Scope-Trennung, können nicht ohne Aufwand rotiert werden und bieten keinen Replay-Schutz. In der Praxis führt das zu API-Keys, die jahrelang gültig bleiben, in Repositories landen und nach dem nächsten Security-Incident manuell rotiert werden müssen. Die folgenden Abschnitte zeigen, welches Authentifizierungsverfahren wann das richtige ist – und was jedes Verfahren konkret implementiert.
2. API-Keys: einfach, aber begrenzt
API-Keys sind statische Geheimnisse, die im Request-Header (X-API-Key oder Authorization: ApiKey) oder als Query-Parameter übertragen werden. Sie sind einfach auszustellen und zu validieren, haben aber strukturelle Schwächen. Ohne Expiry müssen sie manuell rotiert werden. Ohne Scope-Bindung gewähren sie immer vollen Zugriff. Ohne Signatur lässt sich aus einem abgefangenen API-Key sofort ein gültiger Request konstruieren. Trotzdem sind sie in bestimmten Szenarien das richtige Mittel: interne Tools, Development-Umgebungen, sehr einfache APIs mit wenigen, bekannten Consumern.
Die korrekte Implementierung von API-Keys: Sie werden serverseitig als Bcrypt-Hash gespeichert, nicht im Klartext. Bei der Ausstellung erhält der Client den Klartextwert genau einmal – danach ist er nicht mehr abrufbar. API-Keys sollten kryptographisch zufällig sein (mindestens 256 Bit Entropie), einem Präfix-Schema folgen (mk_live_..., mk_test_...), um Umgebungsverwechslungen zu verhindern, und in Logs niemals vollständig erscheinen (nur erste und letzte 4 Zeichen). Für produktive Szenarien mit Drittentwicklern oder User-Delegation sind API-Keys nicht ausreichend – hier beginnt OAuth2.
# API-Key patterns — correct usage
# In Authorization header (preferred over query param)
curl -H "Authorization: ApiKey mk_live_a3f9c8b2d7e4f1..." \
https://api.mironsoft.de/v1/products
# X-API-Key header (common alternative)
curl -H "X-API-Key: mk_live_a3f9c8b2d7e4f1..." \
https://api.mironsoft.de/v1/products
# NEVER in query string — appears in server logs and browser history
# BAD: GET /products?api_key=mk_live_a3f9c8b2d7e4f1
# Rate limiting by API-Key (response headers)
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1748476800
Retry-After: 3600
# 429 Too Many Requests when limit exceeded
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
Content-Type: application/problem+json
{ "type": "https://mironsoft.de/errors/rate-limit-exceeded",
"title": "Rate Limit überschritten", "status": 429 }
3. Bearer Token und JWT: zustandslose Authentifizierung
Bearer Token nach RFC 6750 werden im Authorization: Bearer <token>-Header übertragen. Der Name "Bearer" bedeutet: wer den Token hat, ist berechtigt – ohne weitere Identitätsüberprüfung. Das macht sie portabel und zustandslos, aber auch anfällig für Token-Diebstahl. JSON Web Tokens (JWT, RFC 7519) sind das verbreitetste Bearer-Token-Format für APIs. Ein JWT trägt Claims – strukturierte Daten wie User-ID, Rollen, Scopes und Ablaufzeit – direkt im signierten Token-Payload, ohne dass der Server den Token in einer Datenbank nachschauen muss.
Die Signatur eines JWT wird mit einem privaten Schlüssel (RS256, ES256) oder einem symmetrischen Geheimnis (HS256) erzeugt. Der empfangende Server validiert die Signatur mit dem öffentlichen Schlüssel oder dem geteilten Geheimnis. Kritische Validierungen: exp-Claim (Ablaufzeit), iss-Claim (Aussteller), aud-Claim (beabsichtigter Empfänger) und alg-Header (niemals none akzeptieren). JWTs sind nicht verschlüsselt – alle Claims im Payload sind Base64-decodierbar. Sensible Daten (Passwörter, Kreditkartennummern) gehören nicht in JWT-Payloads. Für verschlüsselte Payloads gibt es JWE (JSON Web Encryption).
4. OAuth2 Flows: welcher wofür
OAuth2 (RFC 6749) ist kein Authentifizierungsprotokoll, sondern ein Autorisierungsframework – ein wichtiger Unterschied, der in der Praxis oft verwischt wird. OAuth2 regelt, wie ein Client im Auftrag eines Nutzers Zugriff auf dessen Ressourcen bei einem Resource Server bekommt, ohne das Nutzerpasswort zu kennen. Die vier wichtigsten Flows für REST-APIs sind: Authorization Code (für Webapps und SPAs mit Nutzer-Delegation), Client Credentials (für Machine-to-Machine ohne Nutzerbeteiligung), Device Code (für Geräte ohne Browser) und Implicit (veraltet, nicht mehr verwenden).
Der Client Credentials Flow ist der Standard für M2M-Kommunikation: Der Client authentifiziert sich beim Authorization Server mit Client-ID und Client-Secret, erhält ein Access Token mit den angeforderten Scopes und nutzt dieses Token für API-Requests. Das Token hat eine kurze Lebensdauer (15 Minuten bis 1 Stunde), und der Client fordert automatisch ein neues an, wenn es abläuft. Kein Refresh Token nötig – der Client kann jederzeit ein neues Token holen. Dieser Flow eignet sich für alle Server-zu-Server-Integrationen: Microservices, Cronjobs, Webhooks, Datenimporte.
# OAuth2 Client Credentials Flow
# Step 1: Request access token
curl -X POST https://auth.mironsoft.de/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=service-importer" \
-d "client_secret=cs_live_secret..." \
-d "scope=products:read orders:write"
# Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5...",
"token_type": "Bearer",
"expires_in": 900,
"scope": "products:read orders:write"
}
# Step 2: Use token in API requests
curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5..." \
https://api.mironsoft.de/v1/orders
# Token introspection (RFC 7662) — validate opaque tokens
curl -X POST https://auth.mironsoft.de/oauth2/introspect \
-H "Authorization: Basic base64(client_id:client_secret)" \
-d "token=eyJhbGciOiJSUzI1NiIsInR5..."
5. Authorization Code + PKCE: der sichere Browser-Flow
Für SPAs und mobile Apps ist der Authorization Code Flow mit PKCE (Proof Key for Code Exchange, RFC 7636) der einzige sichere OAuth2-Flow. Das Problem: Ein SPA kann kein Client-Secret sicher speichern – JavaScript-Code ist für jeden Nutzer lesbar. PKCE löst das, ohne ein Client-Secret zu benötigen. Der Client generiert ein kryptographisch zufälliges code_verifier, berechnet daraus den code_challenge (SHA-256-Hash, Base64URL-codiert) und sendet diesen mit dem Authorization Request. Der Authorization Server speichert den Challenge. Beim Token Request sendet der Client den ursprünglichen code_verifier. Der Server verifiziert, dass Hash(code_verifier) dem gespeicherten Challenge entspricht – nur der originale Client kann den Token einlösen.
PKCE ist seit OAuth2.1 (in Entwurf) für alle Clients Pflicht, nicht nur für Public Clients. Der Implicit Flow ist seit OAuth2.1 vollständig entfernt – er hat keine Refresh Tokens, gibt Access Tokens direkt im URL-Fragment zurück (erscheinen in Browser-History und Server-Logs) und bietet keinen PKCE-Schutz. Jede neue SPA-Integration sollte Authorization Code + PKCE verwenden, auch wenn der Authorization Server noch Implicit anbietet. OpenID Connect (OIDC) baut auf OAuth2 auf und fügt Authentifizierung hinzu: ein id_token (JWT) mit User-Identity-Claims, ein standardisierter /userinfo-Endpunkt und Discovery via /.well-known/openid-configuration.
6. HMAC Signed Requests: Integrität und Replay-Schutz
HMAC Signed Requests (z.B. AWS Signature Version 4, Webhook-Signaturen) lösen ein Problem, das Bearer Token nicht lösen: Request-Integrität und Replay-Schutz. Mit einem Bearer Token kann ein Angreifer, der die Verbindung abfängt, denselben Token für beliebige Requests wiederverwenden. Bei HMAC-Signaturen wird die Signatur über den vollständigen Request (Methode, Pfad, Query, relevante Header, Body-Hash) und einen Timestamp berechnet. Der Server validiert Signatur und Timestamp – Requests, die älter als 5 Minuten sind, werden abgelehnt. Der Angreifer kann den Request nicht manipulieren oder replayed senden.
Das Muster ist bei Webhook-Callbacks unverzichtbar. Der Webhook-Sender (z.B. Stripe, GitHub) signiert den Request-Body mit einem geteilten Secret und HMAC-SHA-256 und überträgt die Signatur im Header (X-Stripe-Signature, X-Hub-Signature-256). Der Empfänger berechnet die Signatur selbst und vergleicht mit hmac.compare_digest (Constant-Time-Vergleich, um Timing-Angriffe zu verhindern). Ohne diese Validierung kann jeder beliebige HTTP-Client die Webhook-URL aufrufen und Aktionen auslösen. HMAC Signed Requests sind auch der richtige Mechanismus für Partner-APIs, bei denen der Request-Body nicht manipulierbar sein darf.
# HMAC Signed Request — Webhook validation pattern
# Sender: sign request body with shared secret
TIMESTAMP=$(date +%s)
PAYLOAD='{"event":"order.created","orderId":"4711"}'
SECRET="whsec_live_secret..."
SIGNATURE=$(echo -n "${TIMESTAMP}.${PAYLOAD}" | \
openssl dgst -sha256 -hmac "$SECRET" -binary | \
xxd -p -c 256)
curl -X POST https://partner.example.com/webhooks/mironsoft \
-H "Content-Type: application/json" \
-H "X-Mironsoft-Timestamp: $TIMESTAMP" \
-H "X-Mironsoft-Signature: v1=$SIGNATURE" \
-d "$PAYLOAD"
# Receiver: validate signature (pseudocode logic)
# 1. Extract timestamp from header
# 2. Reject if abs(now - timestamp) > 300 seconds (replay protection)
# 3. Compute: expected = HMAC-SHA256(secret, "${timestamp}.${body}")
# 4. Compare: hmac.compare_digest(expected, received) — constant time!
# 5. Store processed event IDs to prevent duplicate processing
7. mTLS: gegenseitige Zertifikatsauthentifizierung
Mutual TLS (mTLS) erweitert das normale TLS-Handshake um gegenseitige Authentifizierung: Nicht nur der Server präsentiert ein Zertifikat, sondern auch der Client. Der Server validiert das Client-Zertifikat gegen eine CA (Certificate Authority) – nur Clients mit gültigem, CA-signiertem Zertifikat bekommen Zugriff. Das ist das stärkste Authentifizierungsverfahren für Microservice-Kommunikation in Zero-Trust-Netzwerken: keine übertragenen Geheimnisse, keine Token-Diebstahl-Risiken, kryptographisch verifizierte Identität auf Netzwerkebene.
mTLS ist in Kubernetes-Umgebungen mit Service-Meshes (Istio, Linkerd) transparent implementiert – jeder Pod bekommt ein kurzlebiges Zertifikat von der Mesh-CA, und mTLS zwischen Services ist automatisch aktiv, ohne Codeänderungen. Für externe APIs ist mTLS aufwändiger, weil Clients Zertifikate verwalten müssen. Es eignet sich besonders für hochsichere B2B-Integrationen (Finanzsektor, Behörden) und für APIs, die aus Compliance-Gründen keine Token-basierte Authentifizierung verwenden können. Die Kombination mTLS + Bearer Token ist möglich: mTLS authentifiziert die Netzwerkidentität (welcher Service), Bearer Token autorisiert die fachliche Aktion (mit welchen Rechten).
8. Token-Sicherheit: Rotation, Revocation und Scope
Token-Sicherheit ist mehr als die Wahl des richtigen Formats. Die wichtigsten Praktiken: kurze Lebensdauern für Access Tokens (15–60 Minuten), längere aber rotierte Refresh Tokens (7–30 Tage, One-Time-Use-Rotation per RFC 6819). Refresh-Token-Rotation bedeutet: jede Nutzung eines Refresh Tokens erzeugt ein neues Refresh Token und invalidiert das alte. Bei gestohlenen Refresh Tokens wird der Angriff spätestens beim nächsten Refresh des legitimen Clients erkannt – der Token ist bereits verbraucht, der Server kann die gesamte Session invalidieren.
Scope-Design ist entscheidend für das Principle of Least Privilege. Statt eines Catch-all-Scopes (api:full_access) werden granulare Scopes definiert: orders:read, orders:write, customers:read. Clients fordern nur die Scopes an, die sie für ihre aktuelle Operation brauchen. Token-Revocation nach RFC 7009 erlaubt sofortige Invalidierung von Access und Refresh Tokens – unverzichtbar bei Sicherheitsvorfällen. JWKS (JSON Web Key Sets) unter /.well-known/jwks.json erlauben Resource Servern, Public Keys für die JWT-Signaturvalidierung automatisch abzurufen und zu rotieren, ohne Konfigurationsänderungen.
9. Verfahren im direkten Vergleich
Die Wahl des Authentifizierungsverfahrens ist keine one-size-fits-all-Entscheidung. Verschiedene Szenarien erfordern verschiedene Verfahren – und manchmal mehrere kombiniert.
| Szenario | Empfohlenes Verfahren | Replay-Schutz | Aufwand |
|---|---|---|---|
| Interne Dev-Tools | API-Key | Nein | Minimal |
| M2M / Microservices | OAuth2 Client Credentials | Durch kurze Expiry | Mittel |
| SPA / Mobile App | OAuth2 Auth Code + PKCE | Durch kurze Expiry | Mittel |
| Webhook-Empfänger | HMAC Signed Requests | Ja (Timestamp) | Niedrig |
| Zero-Trust / B2B | mTLS (+Bearer) | Ja (TLS) | Hoch |
Die häufigste Fehlkombination: OAuth2 für interne Microservice-Kommunikation in einem privaten Kubernetes-Cluster ohne Zero-Trust-Anforderungen einzusetzen, erzeugt Overhead ohne proportionalen Sicherheitsgewinn. In diesem Kontext reicht mTLS durch den Service-Mesh – oder, wenn kein Mesh vorhanden, ein shared JWT mit kurzer Lebensdauer. Die Tabelle zeigt Empfehlungen, keine absoluten Regeln – der konkrete Anwendungsfall, Compliance-Anforderungen und die vorhandene Infrastruktur beeinflussen die finale Entscheidung immer mit.
Mironsoft
API-Security, OAuth2-Implementierung und Token-Strategien
API-Authentifizierung, die Angriffsflächen wirklich reduziert?
Wir analysieren bestehende Authentifizierungsimplementierungen, identifizieren unsichere Muster und implementieren das passende Verfahren – OAuth2, HMAC Signed Requests oder mTLS – für euren konkreten Anwendungsfall.
Security-Audit
Analyse bestehender Token-Strategien, Scope-Design und Rotation-Mechanismen
OAuth2-Setup
Authorization Server, Client Credentials, PKCE-Flow und Refresh-Token-Rotation
Webhook-Security
HMAC-Signaturvalidierung, Replay-Schutz und Idempotenz-Handling implementieren
10. Zusammenfassung
Die Wahl des richtigen API-Authentifizierungsverfahrens ist eine Architekturentscheidung mit langfristigen Auswirkungen. API-Keys sind einfach, aber ohne Expiry, Scope und Replay-Schutz nur für unkritische interne Tools geeignet. Bearer Token mit JWT ermöglichen zustandslose, skalierbare Authentifizierung – aber JWT-Claims sind nicht verschlüsselt und kurze Lebensdauern sind Pflicht. OAuth2 Client Credentials ist der Standard für M2M-Kommunikation, Authorization Code + PKCE für Nutzer-Delegation in SPAs. HMAC Signed Requests sind unverzichtbar für Webhook-Empfänger und Partner-APIs, bei denen Request-Integrität zählt. mTLS ist das stärkste Verfahren für Zero-Trust-Netzwerke.
Verfahren kombinieren statt ersetzen: OAuth2 für Autorisierung und mTLS für Netzwerk-Identität ist keine Redundanz, sondern Defence in Depth. Token-Sicherheit ist kein einmaliges Setup – Refresh-Token-Rotation, Scope-Minimierung und regelmäßige Key-Rotation sind operative Daueraufgaben. Wer diese Prinzipien in die API-Architektur einbaut, baut APIs, die bei einem Credential-Leak nicht vollständig kompromittiert sind.
API-Authentifizierung — Das Wichtigste auf einen Blick
API-Keys
Als Bcrypt-Hash speichern, Klartextwert nur einmal ausgeben, Präfix-Schema (mk_live_), nie vollständig in Logs.
OAuth2 & JWT
Access Token 15–60 Min., Refresh Token rotierend, granulare Scopes, alg:none verweigern, aud/iss validieren.
HMAC Signed Requests
Timestamp im Payload, max. 5 Minuten alt, Constant-Time-Vergleich, verarbeitete Event-IDs speichern.
Scope & Rotation
Least Privilege: nur benötigte Scopes anfordern. Refresh-Token-Rotation. JWKS für automatisches Key-Rollover.
11. FAQ: API-Authentifizierung
1Authentifizierung vs. Autorisierung – was ist der Unterschied?
id_token.2Brauche ich OAuth2 für kleine APIs?
3OAuth2 vs. OpenID Connect?
id_token und /userinfo-Endpunkt.4Warum Implicit Flow vermeiden?
5Wie Replay-Angriffe verhindern?
6API-Keys sicher in Datenbank speichern?
7Wann lohnt sich mTLS?
8Wie funktioniert Refresh-Token-Rotation?
9Was gehört in einen JWT-Payload?
10Webhook-Signaturen korrekt validieren?
hmac.compare_digest (Constant-Time) verwenden. Event-ID speichern gegen Duplikate.