OAuth 2.0 und JWT: Authentifizierung und Autorisierung verständlich erklärt
Sobald eine Web-Anwendung mehr leisten soll als das Ausliefern statischer Inhalte, stellt sich die Frage: Wie weiß die Anwendung, wer ein Nutzer ist und was er tun darf? Begriffe wie OAuth 2.0, JWT, Access Token oder PKCE fallen dann schnell, werden aber häufig durcheinandergeworfen. In diesem Artikel erkläre ich Ihnen, wie moderne Authentifizierung und Autorisierung in Web-Apps und APIs funktionieren, wie OAuth 2.0 und JSON Web Tokens zusammenspielen und welche Sicherheitsentscheidungen Sie in einem Projekt unbedingt treffen müssen.
Authentifizierung und Autorisierung: zwei unterschiedliche Dinge
Bevor wir über Technologien sprechen, lohnt sich ein Blick auf zwei Begriffe, die im Alltag oft synonym verwendet werden, in Wahrheit aber zwei verschiedene Fragen beantworten. Authentifizierung klärt die Frage: Wer sind Sie? Es geht darum, die Identität eines Nutzers zu überprüfen, etwa durch die Eingabe von Benutzername und Passwort oder über einen zweiten Faktor.
Autorisierung klärt dagegen die Frage: Was dürfen Sie? Nachdem feststeht, wer ein Nutzer ist, entscheidet die Autorisierung darüber, auf welche Ressourcen und Funktionen er zugreifen darf. Ein eingeloggter Nutzer ist authentifiziert. Ob er aber die Rechnungen anderer Kunden einsehen darf, ist eine Frage der Autorisierung.
Hinweis: Diese Unterscheidung ist mehr als Wortklauberei. OAuth 2.0 ist im Kern ein Protokoll für Autorisierung, nicht für Authentifizierung. Für die Identitätsprüfung wurde mit OpenID Connect eine eigene Schicht auf OAuth 2.0 aufgesetzt. Wer beides verwechselt, baut schnell unsichere Systeme.
Was ist OAuth 2.0?
OAuth 2.0 ist ein offenes Standard-Framework für Autorisierung. Es löst ein konkretes Problem: Wie kann eine Anwendung im Namen eines Nutzers auf geschützte Ressourcen zugreifen, ohne dass der Nutzer ihr sein Passwort anvertrauen muss? Das klassische Beispiel ist eine App, die auf Ihre Fotos in einem Cloud-Dienst zugreifen möchte. Statt der App Ihr Cloud-Passwort zu geben, erteilen Sie ihr über OAuth eine eng begrenzte Berechtigung.
Der Kern von OAuth 2.0 ist also die delegierte Autorisierung. Anstelle des Passworts erhält die Anwendung ein Access Token, das genau definiert, worauf sie zugreifen darf und wie lange. Dieses Prinzip steckt heute hinter fast jedem „Login mit Google“ oder „Anmelden mit Microsoft“ und hinter dem Großteil aller modernen API-Architekturen.
Die vier Rollen im OAuth-Modell
Um die Abläufe zu verstehen, müssen Sie die vier Beteiligten kennen, die OAuth 2.0 definiert. Sie tauchen in jeder Diskussion über das Thema wieder auf.
Der Authorization Code Flow mit PKCE
OAuth 2.0 kennt mehrere sogenannte Flows, also festgelegte Abläufe für unterschiedliche Anwendungstypen. In der Vergangenheit gab es den Implicit Flow und den Resource Owner Password Credentials Flow. Beide gelten heute als unsicher und werden im modernen Standard nicht mehr empfohlen. Der einzige Flow, den Sie für interaktive Anmeldungen in Web-Apps, Single-Page-Apps und mobilen Apps verwenden sollten, ist der Authorization Code Flow mit PKCE.
PKCE steht für „Proof Key for Code Exchange“ und spricht sich „Pixie“. Es ist eine Erweiterung, die ursprünglich für mobile Apps entwickelt wurde, mittlerweile aber für alle Client-Typen Standard ist. PKCE schützt davor, dass ein abgefangener Authorization Code von einem Angreifer gegen ein Token eingelöst werden kann. Der grobe Ablauf sieht so aus:
Zusätzlich zum PKCE-Mechanismus sollten Sie immer einen state-Parameter mitführen. Dieser schützt gegen Cross-Site-Request-Forgery, während PKCE den Code-Abfangangriff verhindert. Beide Maßnahmen ergänzen sich und sind kein Ersatz füreinander. Ebenso wichtig: Die Redirect-URI muss vom Authorization Server exakt geprüft werden, Zeichen für Zeichen, ohne Wildcards.
Praxis-Tipp: Schreiben Sie den OAuth-Flow nicht selbst. In meinen Projekten setze ich auf etablierte Bibliotheken und Identity-Provider wie Keycloak, Auth0 oder die Microsoft-Identity-Plattform. Eigene Implementierungen sind fehleranfällig, und gerade bei Sicherheitsprotokollen sind kleine Fehler oft große Lücken.
OAuth 2.1: die Konsolidierung der Best Practices
Über die Jahre sind rund um OAuth 2.0 zahlreiche zusätzliche Spezifikationen und Sicherheitsempfehlungen entstanden. OAuth 2.1 fasst diese Entwicklung in einem konsolidierten Standard zusammen. Es kombiniert die ursprüngliche OAuth-2.0-Spezifikation mit der PKCE-Erweiterung und den Security Best Current Practices zu einem einzigen, klar definierten Dokument.
Die wichtigsten Änderungen lassen sich leicht zusammenfassen: PKCE ist nun für alle Clients verpflichtend, auch für vertrauliche. Der unsichere Implicit Flow und der Password Credentials Flow wurden vollständig entfernt. Redirect-URIs müssen exakt verglichen werden, und für öffentliche Clients wird die Rotation von Refresh Tokens zur Pflicht. Wer heute ein neues System plant, sollte sich an OAuth 2.1 orientieren, da es schlicht die sichere Variante dessen ist, was ohnehin als Best Practice gilt.
Was ist ein JWT?
Während OAuth 2.0 den Ablauf beschreibt, sagt der Standard zunächst nichts darüber aus, wie ein Access Token genau aussehen muss. In der Praxis hat sich dafür ein Format durchgesetzt: das JSON Web Token, kurz JWT. Ein JWT ist eine kompakte, URL-sichere Zeichenkette, die Informationen in sich trägt und kryptografisch signiert ist. Es besteht aus drei Teilen, die durch Punkte getrennt sind.
Header, Payload und Signature
Der Header enthält Metadaten, vor allem das verwendete Signaturverfahren, etwa HS256 oder RS256, und gegebenenfalls eine Schlüssel-Kennung. Der Payload enthält die eigentlichen Daten, die sogenannten Claims. Das sind Aussagen über den Nutzer und das Token selbst, beispielsweise die Nutzer-ID, die Gültigkeitsdauer oder die zugewiesenen Rollen. Die Signature schließlich ist eine kryptografische Prüfsumme über Header und Payload, die sicherstellt, dass das Token nicht manipuliert wurde.
Wichtig: Der Payload eines JWT ist nur Base64-kodiert, nicht verschlüsselt. Jeder, der das Token besitzt, kann den Inhalt lesen. Schreiben Sie deshalb niemals sensible Daten wie Passwörter oder Kreditkartennummern in ein JWT. Die Signatur schützt vor Veränderung, nicht vor Einsicht.
Wichtige Claims im Überblick
Bestimmte Claims sind standardisiert und sollten von jedem Resource Server bei der Validierung geprüft werden. Die folgende Tabelle zeigt die wichtigsten.
| Claim | Bedeutung | Zweck bei der Prüfung |
|---|---|---|
| iss | Issuer, der Aussteller des Tokens | Stammt das Token vom erwarteten Authorization Server? |
| sub | Subject, eindeutige ID des Nutzers | Identifiziert, um wen es geht |
| aud | Audience, Zielgruppe des Tokens | Ist die API überhaupt der vorgesehene Empfänger? |
| exp | Expiration, Ablaufzeitpunkt | Ist das Token noch gültig oder bereits abgelaufen? |
| iat | Issued At, Ausstellungszeitpunkt | Wann wurde das Token erzeugt? |
Signaturverfahren: HS256 gegen RS256
Für die Signatur kommen vor allem zwei Verfahren zum Einsatz. HS256 arbeitet symmetrisch, das heißt, derselbe geheime Schlüssel wird zum Signieren und zum Prüfen verwendet. Das ist einfach, eignet sich aber nur, wenn Aussteller und Prüfer derselben vertrauenswürdigen Instanz angehören. Sobald mehrere Dienste das Token prüfen müssen, wird das gemeinsame Geheimnis zum Risiko.
RS256 arbeitet asymmetrisch mit einem Schlüsselpaar. Der Authorization Server signiert mit seinem privaten Schlüssel, und beliebig viele Resource Server können die Signatur mit dem öffentlichen Schlüssel prüfen, ohne das Geheimnis zu kennen. In verteilten Architekturen mit mehreren APIs ist RS256 deshalb fast immer die bessere Wahl.
Access Token und Refresh Token
In einem typischen OAuth-Setup erhalten Sie nach der Anmeldung nicht ein, sondern zwei Tokens, die unterschiedliche Aufgaben erfüllen. Das Verständnis dieser Trennung ist zentral für ein sicheres Design.
Das Access Token ist der Schlüssel zur API. Es wird bei jeder Anfrage mitgeschickt und sollte bewusst kurzlebig sein, oft nur wenige Minuten bis zu einer Stunde. Wird es gestohlen, ist der Schaden zeitlich begrenzt, weil das Token schnell verfällt. Das Refresh Token dagegen ist langlebig und dient ausschließlich dazu, neue Access Tokens zu besorgen, wenn die alten ablaufen. So muss sich der Nutzer nicht ständig neu anmelden.
| Eigenschaft | Access Token | Refresh Token |
|---|---|---|
| Zweck | Zugriff auf die API | Neues Access Token anfordern |
| Lebensdauer | Kurz (Minuten bis Stunde) | Lang (Tage bis Wochen) |
| Wird gesendet an | Resource Server (API) | Nur an den Authorization Server |
| Bei Diebstahl | Begrenzter Schaden | Hohes Risiko, daher Rotation |
Weil das Refresh Token so wertvoll ist, gilt für öffentliche Clients die Refresh-Token-Rotation als Pflicht. Bei jeder Erneuerung wird das alte Refresh Token ungültig und ein neues ausgegeben. Taucht ein bereits verwendetes Refresh Token erneut auf, ist das ein Warnsignal für einen möglichen Diebstahl, und die gesamte Sitzung kann sofort invalidiert werden.
Wo speichert man Tokens sicher?
Die Frage nach der Token-Speicherung im Browser sorgt regelmäßig für Diskussionen, und das zu Recht. Die falsche Entscheidung öffnet Angreifern Tür und Tor. Im Kern geht es um zwei Bedrohungen: Cross-Site-Scripting (XSS) und Cross-Site-Request-Forgery (CSRF).
Das Speichern von Tokens im localStorage ist bequem, aber riskant. Jeder JavaScript-Code, der auf Ihrer Seite läuft, kann darauf zugreifen. Gelingt einem Angreifer eine XSS-Lücke, kann er das Token direkt auslesen und stehlen. Aus diesem Grund rät die OWASP-Community vom localStorage für sensible Tokens ab.
Die sicherere Alternative ist ein httpOnly-Cookie. Auf ein solches Cookie kann JavaScript prinzipiell nicht zugreifen, weshalb es auch bei einer XSS-Lücke nicht direkt ausgelesen werden kann. Cookies bringen allerdings die CSRF-Problematik mit, die Sie über das SameSite-Attribut und zusätzliche Anti-CSRF-Tokens entschärfen müssen.
Praxis-Tipp: Der heute empfohlene Ansatz ist ein hybrides Modell. Das kurzlebige Access Token wird ausschließlich im Arbeitsspeicher der Anwendung gehalten, etwa im State der Single-Page-App, und ist nach einem Seiten-Reload weg. Das langlebige Refresh Token liegt in einem httpOnly-, Secure- und SameSite-Cookie. Beim Laden der Seite holt sich die App über das Cookie still ein neues Access Token. Dieser Ansatz wehrt sowohl XSS als auch CSRF wirksam ab.
Typische Sicherheitsfehler und wie Sie sie vermeiden
In der Praxis sehe ich immer wieder dieselben Fehler. Die gute Nachricht: Die meisten lassen sich mit etwas Sorgfalt vermeiden. Hier die wichtigsten Stolperfallen.
Der alg-none-Angriff
Manche JWT-Bibliotheken akzeptierten in der Vergangenheit Tokens mit dem Header alg gleich none, also ohne Signatur, als gültig. Ein Angreifer konnte so den Payload beliebig verändern, etwa sich selbst eine Administrator-Rolle zuweisen. Akzeptieren Sie auf der Server-Seite niemals den Wert none und geben Sie immer explizit vor, welcher Algorithmus erwartet wird.
Algorithmus-Verwechslung
Bei der sogenannten Algorithm-Confusion-Attacke vertauscht ein Angreifer das erwartete RS256 gegen HS256 und nutzt den öffentlichen Schlüssel als HMAC-Geheimnis. Prüft der Server nicht streng, welches Verfahren er erwartet, gelingt die Fälschung. Legen Sie den erlaubten Algorithmus serverseitig fest und lassen Sie ihn nicht aus dem Token-Header ableiten.
Vergessene Prüfung von iss und aud
Viele Anwendungen prüfen zwar die Signatur, ignorieren aber die Claims iss und aud. Gerade in Multi-Tenant-Umgebungen mit gemeinsamem Schlüssel kann ein Angreifer dann ein für einen Dienst ausgestelltes Token bei einem anderen einreichen. Prüfen Sie deshalb immer Aussteller, Zielgruppe und Ablaufzeit, nicht nur die Signatur.
OpenID Connect: Authentifizierung auf Basis von OAuth
Weil OAuth 2.0 streng genommen nur die Autorisierung regelt, wurde mit OpenID Connect eine dünne Identitätsschicht obendrauf gesetzt. OpenID Connect nutzt die OAuth-Flows, fügt aber ein zusätzliches Token hinzu: das ID Token. Während das Access Token sagt, was die App darf, sagt das ID Token, wer der Nutzer ist.
Das ID Token ist ebenfalls ein JWT und enthält Identitätsinformationen wie die Nutzer-ID (sub), den Aussteller (iss), die Zielgruppe (aud) sowie Ausstellungs- und Ablaufzeit. Man kann es sich wie einen digitalen Ausweis vorstellen, der vom Identity Provider signiert wurde. Wenn Sie einen „Login mit Google“-Button nutzen, steckt fast immer OpenID Connect dahinter. Für Single-Sign-On-Szenarien ist es der etablierte Standard.
Merksatz: Access Token für die API, ID Token für die Identität. Verwenden Sie das ID Token nicht, um Zugriff auf eine API zu autorisieren. Es ist für den Client gedacht, der daraus erfährt, wer sich angemeldet hat, nicht für den Resource Server.
Meine Empfehlung für die Praxis
Wenn ich für einen Kunden eine moderne Web-Anwendung oder eine API absichere, folge ich einigen klaren Leitlinien, die sich über viele Projekte bewährt haben. Sie ersparen Ihnen die meisten Probleme von Anfang an.
Häufige Fragen
Ist ein JWT immer ein OAuth-Token?
Nein. JWT ist ein Token-Format, OAuth 2.0 ist ein Autorisierungs-Framework. OAuth-Access-Tokens sind oft, aber nicht zwingend JWTs. Umgekehrt lassen sich JWTs auch ganz ohne OAuth einsetzen, etwa für klassische Session-Tokens oder zur sicheren Datenübertragung zwischen Diensten.
Wie kann ich ein JWT widerrufen?
Das ist die Kehrseite zustandsloser Tokens. Ein einmal ausgestelltes, signiertes JWT bleibt bis zum Ablauf gültig. Genau deshalb hält man Access Tokens kurzlebig. Soll ein Token sofort entzogen werden, brauchen Sie zusätzliche Mechanismen wie eine Sperrliste (Denylist) oder eine Token-Introspection beim Authorization Server.
Fazit
OAuth 2.0 und JWT sind heute das Rückgrat der Authentifizierung und Autorisierung in Web-Apps und APIs. Wichtig ist, die Rollen klar zu trennen: OAuth 2.0 regelt, was eine Anwendung darf, OpenID Connect klärt, wer der Nutzer ist, und JWT ist das Format, in dem diese Informationen sicher transportiert werden. Wer den Authorization Code Flow mit PKCE einsetzt, Tokens richtig speichert und die typischen Fehler bei der Validierung vermeidet, baut Systeme, die sowohl benutzerfreundlich als auch robust gegen die gängigen Angriffe sind.
Meine Empfehlung lautet, an dieser Stelle nicht zu experimentieren, sondern auf bewährte Standards und ausgereifte Bibliotheken zu setzen. Sicherheit ist kein Feature, das man nachträglich ergänzt, sondern eine Grundentscheidung, die von Anfang an in die Architektur gehört.
Authentifizierung sicher umsetzen?
Sie planen eine neue Web-App oder API und möchten Authentifizierung und Autorisierung von Anfang an richtig aufsetzen? Ich unterstütze Sie bei Architektur, OAuth-Integration und Token-Sicherheit. Lassen Sie uns Ihr Projekt besprechen.