Die Anleitung

Welchen Ablauf soll ich wählen?

Ein „Flow“ (oder „Grant“) ist die Art, wie eine Anwendung ihre Token erhält. Es gibt mehrere, weil Anwendungen sehr verschieden sind: Eine Website, eine mobile App, ein Fernseher, ein Dienst ohne Benutzer… haben nicht dieselben Einschränkungen oder dieselben zu schützenden Geheimnisse.

Siehe auch: die Abläufe als Sequenzdiagramme · erweiterte Funktionen erklärt (PAR, JAR, JARM, DPoP, CIBA) · die Zeitleiste von OAuth und OpenID Connect

In zwei Fragen

  1. Meldet sich eine Person an? Nein, ein Dienst spricht mit einem anderen Dienst → Client Credentials.
  2. Ja. Wo läuft die Anwendung?
    • Website, mobile Anwendung, Single-Page-Anwendung (SPA), Desktop-Anwendung, mit Browser → Authorization Code + PKCE. Das ist die Antwort in # % der Fälle.
    • Gerät ohne Browser oder Tastatur (Fernseher, Konsole, vernetztes Gerät, Kommandozeilenwerkzeug) → Device Code.

Alles andere gibt es aus historischen Gründen oder für besondere Bedürfnisse. Refresh Token ist kein Anmeldeablauf: Es ergänzt, um die Sitzung am Leben zu halten.

Warum so viele Abläufe?

OAuth 2.0 (2012) musste sowohl Servern dienen, die ein Geheimnis aufbewahren können, als auch Browser-Anwendungen, die das nicht können. Daher implicit für SPAs, password für „vertrauenswürdige“ Anwendungen und code für Server. Mit den Jahren wurde klar, dass Tokens in der URL durchsickerten (implicit) und dass die Weitergabe des Passworts an die Anwendung den ganzen Sinn zunichtemachte (password). OAuth 2.1 und die aktuellen Sicherheitsempfehlungen haben deshalb alles auf Code + PKCE zurückgeführt und Client Credentials und Device für ihre eigenen Fälle beibehalten. OIDC hat den Hybrid-Ablauf hinzugefügt, um die Identität sofort zu erhalten.

Die Abläufe, einer nach dem anderen

Authorization Code + PKCEDer Standardablauf für jede Person, die sich anmeldet.Empfohlen

Einsetzen, wenn: sich eine Person bei einer Website (mit oder ohne Server), einer SPA, einer mobilen oder Desktop-Anwendung anmeldet. Mit einem Server, der ein Geheimnis aufbewahren kann, fügen Sie das client_secret hinzu; ohne (SPA, mobil) genügt PKCE.

Warum es das gibt: Der Browser erhält nur einen kurzlebigen Code zur einmaligen Verwendung; die Tokens gehen direkt vom Server der Anwendung zum OP („Back Channel“). PKCE bindet den Code an den, der ihn angefordert hat, sodass ein abgefangener Code für niemand anderen nützlich ist.

Fallstricke: PKCE vergessen (jetzt auch für vertrauliche Clients Pflicht), state und nonce nicht prüfen, zu weit gefasste redirect_uris akzeptieren, Tokens in localStorage bei einer SPA.

Schritt-für-Schritt-Anleitung:

  1. Die Anwendung erzeugt code_verifier (ein zufälliges Geheimnis), state, nonce und berechnet code_challenge = SHA-256(code_verifier).
  2. Es schickt die Person zu /authorize?response_type=code&code_challenge=…&state=…&nonce=….
  3. Der OP authentifiziert die Person und schickt sie dann zu redirect_uri?code=…&state=… zurück.
  4. Die Anwendung ruft /token mit dem Code und dem code_verifier auf (und ihrem Geheimnis, falls vorhanden).
  5. Es empfängt das ID-Token, das Access-Token (und das Refresh-Token) und prüft dann die Signatur, iss, aud und nonce.
Hybrid (code id_token, code token…)Code plus ID-Token direkt in der Weiterleitung.Besondere Fälle

Einsetzen, wenn: die Anwendung die Identität sofort braucht (vor dem Code-Austausch), zum Beispiel für die serverseitige Sitzungsvalidierung oder weil eine ältere Bibliothek (ASP.NET, Java EE) es standardmäßig konfiguriert.

Warum es das gibt: OIDC wollte erlauben, die Identität sofort zu lesen und dabei den Code beizubehalten, um Tokens sicher zu erhalten. c_hash und at_hash im ID-Token binden Code und Access-Token an diese Identität.

Fallstricke: Tokens im URL-Fragment (sichtbar für Verlauf und Skripte), ungeprüfte c_hash/at_hash und eine vergessene Pflicht-nonce. Bevorzugen Sie den einfachen Code-Flow, sofern nichts dagegen spricht.

Schritt-für-Schritt-Anleitung:

  1. /authorize?response_type=code id_token&nonce=… (oder code token, code id_token token).
  2. Der OP gibt #code=…&id_token=…&state=… im Fragment (response_mode=fragment standardmäßig) oder per POST (form_post) zurück.
  3. Die Anwendung prüft das ID-Token und sein c_hash.
  4. Es tauscht den Code gegen die anderen Tokens, wie im Code-Flow.
Implicit (id_token, id_token token)Die Tokens kommen direkt in der URL an.Nicht empfohlen

Einsetzen, wenn: bei Neuentwicklungen fast nie. Man trifft es in alten SPAs an oder um zu prüfen, ob eine Anwendung es wirklich verbietet.

Warum es das gibt: Bevor Browser Aufrufe zwischen Origins (CORS) und PKCE beherrschten, konnte eine SPA /token nicht aufrufen und bekam die Tokens deshalb direkt.

Fallstricke: Das Token reist in der URL: Verlauf, Proxy-Logs, Referer-Header, Erweiterungen. Kein Refresh-Token, keine Bindung an den Aufrufer. Aus OAuth 2.1 entfernt.

Schritt-für-Schritt-Anleitung:

  1. /authorize?response_type=id_token token&nonce=….
  2. Der OP liefert #id_token=…&access_token=…&state=….
  3. Ein Skript auf der Seite liest das Fragment und prüft das Token.
Client CredentialsKeine Person: Der Dienst authentifiziert sich selbst.Maschine zu Maschine

Einsetzen, wenn: ein Dienst, ein geplanter Job oder ein Daemon eine API in eigenem Namen aufruft: Synchronisation, Nachtjob, Microservices, die miteinander sprechen.

Warum es das gibt: Hinter vielen API-Aufrufen steht keine Person. Der Client weist seine Identität nach (Geheimnis oder besser: signierte Assertion) und erhält ein auf seine Scopes begrenztes Access-Token.

Fallstricke: kein ID-Token oder Refresh-Token (das ist normal). Legen Sie dieses Geheimnis nie in eine verteilte Anwendung (mobil, SPA). Vergeben Sie nur die nötigsten Scopes und rotieren Sie das Geheimnis.

Schritt-für-Schritt-Anleitung:

  1. POST /token mit grant_type=client_credentials, scope=… und der Client-Authentifizierung (Basic-Secret oder im Body).
  2. Der OP antwortet mit einem Access-Token.
  3. Der Dienst sendet es an die API: Authorization: Bearer ….
Refresh TokenEin Access-Token erneuern, ohne die Person erneut zu fragen.Ergänzung

Einsetzen, wenn: Sie kurzlebige Access-Tokens (einige Minuten) wollen und die Person trotzdem lange angemeldet bleibt. Wird mit dem Scope offline_access angefordert.

Warum es das gibt: Je länger ein Token lebt, desto schlimmer ist sein Diebstahl. Das Refresh-Token bleibt auf Anwendungsseite, fern von den APIs, und dient nur zur Erneuerung.

Fallstricke: Ein gestohlenes Refresh-Token bedeutet verlängerten Zugriff: sichere Speicherung, Rotation (bei jeder Nutzung ein neues, das alte wird ungültig) und Erkennung von Wiederverwendung.

Schritt-für-Schritt-Anleitung:

  1. POST /token mit grant_type=refresh_token&refresh_token=….
  2. Der OP gibt ein neues Access-Token zurück (und oft ein neues Refresh-Token, wobei das alte widerrufen wird).
Device Code (RFC 8628)Auf einem anderen Gerät anmelden.Geräte ohne Browser

Einsetzen, wenn: Fernseher, Konsole, vernetztes Gerät, Drucker, Kommandozeilenwerkzeug: Das Gerät hat keinen Browser oder keine bequeme Tastatur.

Warum es das gibt: Ein Passwort mit einer Fernbedienung einzutippen ist mühsam und riskant. Ein kurzer Code wird angezeigt; die Person gibt ihn auf ihrem Telefon oder Computer ein, wo sie sich ganz normal authentifiziert.

Fallstricke: kurzlebiger Einmalcode, nicht zu schnell abfragen (slow_down) und Versuchsbegrenzungen, damit ein Code nicht erraten werden kann. Phishing ist möglich: Zeigen Sie klar, was die Person autorisiert.

Schritt-für-Schritt-Anleitung:

  1. Das Gerät ruft /device_authorization auf und erhält device_code, user_code und die Verifizierungsadresse.
  2. Es zeigt „Gehen Sie zu … und geben Sie ABCD-EFGH ein“.
  3. Die Person authentifiziert sich und gibt den Code auf ihrem Telefon ein.
  4. Währenddessen fragt das Gerät /token mit dem device_code ab. Zuerst authorization_pending, dann die Tokens.
Resource Owner Password CredentialsDie Anwendung erhält das Passwort direkt.Nicht empfohlen

Einsetzen, wenn: es zu vermeiden ist. Manchmal für eine Migration von einem alten System oder für automatisierte Tests in kontrollierter Umgebung geduldet.

Warum es das gibt: ein Übergang für Anwendungen, die bereits Passwörter entgegennahmen, ohne ihre Oberfläche zu ändern.

Fallstricke: Die Anwendung sieht das Passwort: genau das, was OIDC vermeiden will. Keine Multi-Faktor-Authentifizierung, kein SSO, leichteres Phishing. Aus OAuth 2.1 entfernt.

Schritt-für-Schritt-Anleitung:

  1. POST /token mit grant_type=password&username=…&password=….
  2. Der OP antwortet mit den Tokens oder lehnt ab, wenn ein zweiter Faktor verlangt wird.

Auch in der Praxis

  • private_key_jwt und JWT Bearer (RFC 7523): Ein Dienst weist seine Identität mit einer signierten Assertion statt mit einem gemeinsamen Geheimnis nach. Ideal für den Austausch zwischen Systemen. In ID-Kit auf Seite des Test-Providers; auf Seite der Testanwendung noch nicht.
  • Token Exchange (RFC 8693): ein Token gegen ein anderes tauschen, für eine API, die im Namen der Person eine andere API aufruft. In ID-Kit.
  • PAR und JAR (RFC 9126 und 9101): Die Autorisierungsanfrage wird von Server zu Server übermittelt oder signiert. In ID-Kit: Test-Provider (PAR und JAR) und Testanwendung (PAR).
  • CIBA : Die Authentifizierung erfolgt über einen anderen Kanal, vom Server ausgelöst (Callcenter, Bank). In ID-Kit (Test-Provider, Poll-Modus).

Alle Details in Bildern: Sequenzdiagramme.

Die dazugehörigen Schutzmaßnahmen

  • PKCE: beweist, dass derjenige, der den Code einlöst, auch derjenige ist, der ihn angefordert hat.
  • state: bindet die Antwort an die Anfrage, gegen CSRF.
  • nonce: bindet das ID-Token an die Sitzung der Anwendung, gegen Replay.
  • Exakte redirect_uri: Der OP sendet den Code nur an eine registrierte Adresse, Zeichen für Zeichen.

Testen Sie jeden Ablauf. Der Testprovider von ID-Kit kann all diese Abläufe spielen, mit simulierten Fehlern; die Testanwendung führt sie gegen Ihren echten Provider aus.