auth pkce - shedowe19/routely GitHub Wiki

Modul: Auth - OAuth2 PKCE Flow

Zweck

Detaillierte Dokumentation des OAuth2-Authentifizierungsablaufs mit PKCE (Proof Key for Code Exchange).

Kontext

PKCE- und OAuth-Hilfsfunktionen sind vorhanden. Der erreichbare SetupScreen nutzt ausschließlich die manuelle Token-Eingabe. Es gibt derzeit keinen angebundenen Browser-Login oder Code-Austausch; der deklarierte Callback allein bildet keinen vollständigen Ablauf.

Wichtige Dateien

  • app/src/main/kotlin/de/traewelling/app/util/OAuthHelper.kt
  • app/src/main/kotlin/de/traewelling/app/viewmodel/AuthViewModel.kt
  • app/src/main/kotlin/de/traewelling/app/data/repository/AuthRepository.kt
  • app/src/main/kotlin/de/traewelling/app/data/repository/OAuthRefreshError.kt
  • app/src/main/kotlin/de/traewelling/app/data/api/TraewellingApiService.kt (enthält OAuthApiService)
  • app/src/main/AndroidManifest.xml

Vorhandene Hilfsfunktionen

  • OAuthHelper.generateCodeVerifier() erzeugt 64 zufällige Bytes und kodiert sie Base64-URL ohne Padding.
  • generateCodeChallenge() berechnet SHA-256 und kodiert das Ergebnis als Base64-URL.
  • buildAuthorizationUrl() setzt an /oauth/authorize unter anderem code_challenge, code_challenge_method=S256 und state. Callback-Code und State können extrahiert werden.
  • AuthRepository.exchangeCodeForToken() sendet grant_type=authorization_code, Client-Konfiguration, Redirect-URI, code und optional code_verifier an POST /oauth/token. code_challenge gehört zur Autorisierungs-URL und wird hier nicht gesendet.
  • refreshAccessToken() sendet grant_type=refresh_token, Client-Konfiguration und gespeichertes Refresh-Token an denselben Endpunkt. Eine erfolgreiche Antwort ersetzt den Refresh-Token nur durch einen nicht leeren Ersatz; fehlt dieser oder ist er leer, bleibt der bisherige für die nächste Erneuerung erhalten. Ein fehlender oder leerer Access-Token wird weiterhin abgelehnt, ohne Zugangsdaten zu verändern. Der Aufruf erfolgt derzeit nicht automatisch aus ViewModel oder Interceptor.

Der Fehlerpfad unterscheidet den OAuth-Fehlercode vom HTTP-Status: Nur HTTP 400/401/403 mit ausdrücklich erkanntem error = "invalid_grant" darf die weiterhin exakt passende Sitzung löschen. OAuthRefreshError akzeptiert dafür ausschließlich ein vollständig gültiges UTF-8-JSON-Objekt bis 16 KiB mit genau einem stringförmigen error-Feld. Fehlendes, mehrdeutiges, ungültiges oder größeres Fehler-JSON liefert keinen Löschbeleg. invalid_client, invalid_request, invalid_scope, unbekannte Fehler und ein bloßes 401/403 erhalten die Sitzung; ebenso Netzwerk-, Rate-Limit- und Serverfehler. Der Fehler wird dem Aufrufer weitergegeben, nicht als erfolgreiche Erneuerung ausgegeben.

Dieser korrigierte S2-Vertrag folgt RFC 6749, Abschnitt 5.2 und Abschnitt 6: Clientfehler sind kein Beleg für ein ungültiges Nutzer-Grant, ein neuer Refresh-Token ist optional. Revisions-/Snapshot-Vergleiche verhindern weiterhin Änderungen oder Löschungen nach Sitzungswechsel, auch bei erneutem Login mit demselben Token. Coroutine-Abbruch wird propagiert; nach einer abgebrochenen Antwort darf weder gespeichert noch gelöscht werden. Der historische Befund steht im Main-Review.

Die Manifest-URI traewelling://oauth-callback ist registriert. Eine passende Verarbeitung des Callback-Codes, des PKCE-Verifiers und des States ist in MainActivity nicht angebunden.

PreferencesManager Keys für Auth

Key Typ Beschreibung
server_url String Träwelling-Server URL
access_token String Bearer Token
refresh_token String Refresh Token
client_id String OAuth Client ID
client_secret String OAuth Client Secret

Diese Keys gehören zur revisionsgeschützten Session-Verwaltung unter Auth. Der manuelle Login benötigt keine Client-ID und entfernt alte OAuth-Konfiguration bei einer neuen validierten Anmeldung. Ein registrierter Callback ist weiterhin kein Beleg für einen vollständigen Browser-Login.

Offene Fragen

  • TODO: Vor produktiver OAuth-Anbindung parallele Refreshversuche zusammenführen. Bei Rotation kann die zweite invalid_grant-Antwort vor der ersten erfolgreichen Tokenantwort die noch passende Sitzung löschen. Der Helfer ist derzeit nicht produktiv aufgerufen; dies bleibt ein Integrationsrisiko und ist kein neuer Fehler des erreichbaren manuellen Logins. Siehe Nachreview.

  • TODO: Vollständigen OAuth-UI-Ablauf mit Callback-Verarbeitung, State-Prüfung und Token-Erneuerung anbinden. Der bestehende manuelle Token-Login verwendet kein PKCE.

Verwandte Seiten

⚠️ **GitHub.com Fallback** ⚠️