Zusaetzlicher Anmeldeweg neben Benutzername/Passwort. Der Login-Screen holt
die konfigurierten Provider von GET /api/auth/oidc/providers; ohne Provider
oder gegen einen aelteren Server bleibt der Screen unveraendert.
Die App laeuft als Public Client: Authorization Code Flow mit PKCE in einer
ASWebAuthenticationSession (nie ein WKWebView), ohne Client Secret. Das
ID-Token wird an POST /api/auth/oidc/exchange gegen ein Calendarr-Token
getauscht; die Antwort hat dieselbe Form wie der Passwort-Login, sodass der
bestehende Session-Pfad unveraendert weiterlaeuft.
- OIDCAuthenticator kapselt Discovery, PKCE-Request, Code-Tausch und die
stille Erneuerung. Der AuthState mit dem Refresh-Token liegt in der
Keychain (kSecAttrAccessibleAfterFirstUnlock) und wird beim Logout aus
beiden Zugriffsgruppen entfernt.
- OIDCSessionRefresher erneuert die Sitzung beim Start, wenn das
Calendarr-Token binnen 24 h ablaeuft — ohne Browser, ueber den
Refresh-Token des Providers.
- Die angefragten Scopes kommen vom Server (mobile_scopes); ein Scope, den
der Provider nicht kennt, wuerde die ganze Anfrage scheitern lassen.
- Bei aktiviertem gefuehrten Zugriff weicht AppAuth auf SFSafariViewController
aus, dessen Redirect nur ueber ein registriertes URL-Schema zurueckkaeme.
Da das App-Target seine Info.plist generiert und CFBundleURLTypes dort
nicht setzbar ist, wird der Fall vorab sauber abgelehnt statt endlos auf
einen Callback zu warten, der nicht kommen kann.
- Abbrueche werden mit Fehlerdomaene geprueft (user- und programCanceled) und
still behandelt; alle uebrigen Fehler tragen Domain, Code und OAuth-Fehler
ins DEBUG-Log, statt spurlos zu verschwinden.
project.pbxproj: AppAuth-iOS 1.7.5 als SPM-Abhaengigkeit, nur am App-Target.
OTHER_LDFLAGS bekommt -ObjC, weil OIDAuthState+IOS.m ausschliesslich eine
Kategorie enthaelt und ohne Symbol sonst wegoptimiert werden koennte.
Achtung: mangels macOS/Xcode ist dieser Stand nicht kompiliert. Beim ersten
Oeffnen loest Xcode das Paket auf und legt Package.resolved an; die bitte
mit committen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>