Thema: Delphi OAuth2 erste Schritte

Einzelnen Beitrag anzeigen

Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.639 Beiträge
 
#2

AW: OAuth2 erste Schritte

  Alt 2. Nov 2022, 11:12
Puh. Vorneweg: OAuth ist nicht ohne. Im IT-Security Bereich gibt es einen running gag: "Man kann es einfach haben, oder sicher. Such Dir eins aus."

Der ganze "redirect-Tanz" über den default-Browser wird gemacht, damit a) der Benutzer seine Nutzerdaten (Benutzername, Passwort, 2FA Code etc.pp.) niemals an einen fremden Client (fremd aus Sicht des Identity Providers, im Falle von Azure also Fremd aus Sicht von Microsoft) gibt, und damit b) nach erfolgter Authentifizierung ein für den User individuelles Token möglichst sicher und möglichst nicht abfangbar an den Client übergeben wird.

Das bedeutet ein Client (in dem Fall Euer Tool das Mails abholen soll) öffnet eine Authentifizierungs-Anfrage über das OS, in dem es sagt: OS, öffne mal https://login.whatever.dings/ zum Anmelden. Dabei übergibt der Client dann die notwendigen Auth-Parameter (Client Id, benötigte Scopes, welche Tokens er gerne hätte, wohin der redirect nach erfolgter Authentifizierung passiert, eine Nonce, ggf. Zustandsinfos, optional schon ein vorausgefüllter Benutzername etc.).

Der Identity Provider prüft dann ob für der Client der redirect erlaubt ist, ob die Scopes in Ordnung sind etc. und wenn das alles passt meldet er dann den Benutzer bei sich an. Danach wird, je nach sogenanntem Grant Type, mit dem Redirect zur Anwendung entweder direkt die Tokens oder ein Authorization Code an den Client übergeben.

Der redirect kann entweder ein http-Call auf Localhost sein, den der Browser dann ausführt, ODER aber auch ein eigenes Protokoll. Bsp: mycustomapp://login - wenn Du hinter mycustomapp:// beim Betriebssystem Deine Anwendung registriert hast wird der Browser dem OS sagen starte mal die App hinter mycustomapp mit den Parametern aus der Url.

Meist zeigt ein Client nach dem Redirect eine Seite an die sagt: "Du Benutzer, das hat geklappt, Du bist jetzt hier eingeloggt. Mach bitte den Tab hier zu.". Oder er versucht sogar, den Tab selber mit JS zu schließen. Somit hast Du nicht zig Tabs offen.

Dass die Anwendungen lokal einen Http-Server aufmachen um den redirect (und damit die Tokens bzw. den Auth code) anzunehmen ist zwar gängig, ABER dazu müsstest Du eigentlich garantieren können das ein bestimmter Port auf allen Maschinen auf denen das laufen soll frei ist. Zuverlässiger ist da dann entweder die custom app-Registrierung oder aber ein zentraler Server im Internet auf den redirected wird, und mit dem der Client im Hintergrund dann die Daten austauscht (das macht z.B. Postman so). Ich würde hier am ehesten auf Custom App Registrierung gehen. Ist deutlich zuverlässiger und erfordert nicht den Betrieb eines Dienstes im Internet zum Datenaustausch. Erfordert allerdings ein bisschen mehr Code, weil das OS ja eine zweite Instanz Deines Programmes öffnet durch den Link, und die muss dann die erste finden und ihr mittels Inter-Prozess-Kommunikation die Daten durchreichen.

Wenn der Client gleich die Tokens bekommt ist er damit auch Authentifiziert und kann damit arbeiten. Bekommt er einen Auth-Code muss er den jetzt nochmal mit seinem Client-Secret und ggf. einem PKCE-Code Verifier beim IdP gegen das eigentliche Token austauschen.

Damit kommen wir zu den Token-Arten. Ein Access-Token ist üblicherweise nur eine gewisse Zeit lang gültig. Je nach Dienst wenige Minuten bis zu ein paar Stunden. Das macht man, da ein Token das abgefangen wird so lange wie es eben gültig ist sozusagen als Generalschlüssel funktioniert, und ein Angreifer damit jede Menge Schindluder treiben kann. Damit Du nicht jedesmal den Benutzer für eine erneute Anmeldung fragen musst, wenn das Access-Token abläuft, gibt es sogenannte Refresh-Tokens. Das hebt sich der Client in einem möglichst sicheren Ort auf. Wenn das Access-Token abläuft kann der Client mit dem Refresh-Token zum IdP gehen und sich dort ein neues, frisches Access-Token abholen. In aller Regel sind die Refresh-Tokens nur einmal gültig und der Client bekommt mit dem Access-Token auch gleich ein neues Refresh-Token zurück das er dann beim nächsten Mal benutzen soll.

Also konkret zu Deinen Fragen:
1.) Frage nach einen Refresh-Token und merke ihn Dir. Damit musst Du einen Benutzer nur genau einmal anmelden. (Auch Refresh-Tokens laufen irgendwann mal ab, aber meist leben die sehr lange bzw. können sehr lange erneuert werden, z.B. ein ganzes Jahr).
2.) Da kann ich Dir nix zu sagen, ich kenne die Komponenten nicht, nur das OAuth-Protokoll
3.) Auch hier wieder: Benutze das abgelegte Refresh-Token um einen frischen Access-Token zu holen, mit dem solltest Du dann immer wieder Mails holen können.
4.) Ja, Refresh-Token
5.) Das machst Du als Anbieter Deines Clients. Wenn die Oma Thunderbird selber baut und vertreibt, braucht sie Azure. Ansonsten macht das Mozilla für ihren eignen Thunderbird-Client bei sich einmal und dann ist gut.
6.) Was meinst Du mit Deinen Zugangsdaten? Meinst Du die Client-Infos oder meinst Du wirklich Benutzername/Kennwort?
7.) An den IdP selber zurück redirecten bringt Dir ja nix, weil dann die Antwort für die Tokens ja nie in Deinem Client ankommt. Wie gesagt, der Redirect geht (entweder direkt oder indirekt) zu Deinem Client um die Auth-Antwort des IdP an Deinen Client zu übergeben. http://localhost:port/ geht, ist aber unsicher weil a) jemand anderes auf dem Port einen listener aufmachen kann und damit die Tokens abfangen kann und b) sollte alles was Auth betrifft eh immer https sein und das geht dann nur mit Self-Signed Zertifikaten und das ist ehrlich gesagt ein großes Geschiss. Indirekt über einen Service im Internet ist aufwändig (wie gesagt, Postman macht das so, aber die haben auch viel Kohle . Custom-App Registration ist vermutlich der beste und sicherste Weg. Und ja, die Url muss dem IdP vorher bekannt sein, weil sonst könnte ja jemand der Deine Client-Id kennt (die wird offen in der Url übertragen, ist also nicht sicher), auch einen Login machen und sagen: "Du IdP, Ich bin [Client Id Deines Tool], melde mal den Benutzer für mich an und schicke den Token an https://boeser-token-klauer.de/login". Und dann liest der Angreifer locker flockig alle Mails. Das willst Du nicht
Deswegen musst Du als Client-Anbieter dem IdP vorher sagen, wohin er die Tokens schicken darf.

Und ja, die Doku zu Azure und OWA etc. pp. ist.. sagen wir mal sehr unglücklich bis gar nicht versioniert. Die Daten da ändern sich alle viertel bis halbe Jahre (das Web bewegt sich leider superschnell), und ältere Texte werden - leider - wenn sich was ändert nicht nochmal geprüft und dazu geschrieben, Du der Scope da hat sich in den letzten 3 Jahren fünfmal geändert, der aktuelle ist xyz.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat