Security Podcast

OpenID Connect und SSO

Ausweise im Netz

OpenID Connect und SSO werden oft in einem Atemzug genannt. Doch was ist OpenID Connect eigentlich genau? Ein Framework, ein Protokoll oder ein Produkt? Und welche Verbindung gibt es mit OAuth2? Darüber, und wie OpenID Connect im Rahmen von SSO-Verfahren funktioniert, sprechen Christoph Iserlohn, Simon Kölsch und Stefan Bodewig in dieser Folge.
Weitere Episoden anhören

Shownotes & Links

Feedback

Falls ihr Fragen oder Anregungen habt, schreibt uns gerne eine E-Mail an [email protected].

Transkript

Transkript ausklappen / einklappen

Christoph: Hallo und herzlich Willkommen zur achten Ausgabe des INNOQ Security Podcast. Wie auch in den letzten beiden Folgen beschäftigen wir uns weiter mit dem großen Themenkomplex ‚Autorisierung und Authentifizierung‘ und diesmal speziell mit dem Thema ‚OpenID Connect‘. Und dazu habe ich wieder zwei Gäste bei mir. Das ist einmal der Stefan, hallo Stefan!

Stefan: Hallo Christoph!

Christoph: Und der Simon, hallo Simon!

Simon: Hallo, ihr zwo!

Christoph: So, bevor wir über OpenID Connect reden würde ich gerne noch über etwas anderes reden, und zwar über SSO. Und zwar aus dem Grund, weil SSO bei mir immer im Zusammenhang mit OpenID Connect genannt wird und das wohl der, scheinbar der Use Case dafür ist. Aber deshalb sollten wir dann erstmal klären was denn überhaupt SSO heißt und was dahintersteckt.

Simon: Naja, also der End-User kommt mit Single Sign On wahrscheinlich immer so in Berührung, dass er halt immer sein Passwort nur einmal eingibt und ist dann eingeloggt in den ganzen Applikationen, die er so besucht. Und manchmal gibt es so eine Redirect-Schleife in dem Browser und dann kann man die Anwendung ganz normal nutzen. Wichtig dabei ist, dass das Single in Single Sign On eigentlich dafürsteht, dass es für den User eine Identität gibt, die er in verschiedenen Applikationen nutzt. Das hat den Vorteil, dass ich nicht eine Benutzeranmeldung in jeder Applikation bauen muss, Session Management, alles was so dazugehört, sondern dass der Benutzer an einer Stelle sein Passwort eingibt. Ein zentraler Provider, der diese Identität dann quasi zu Verfügung stellt und alle anderen Applikationen vertrauen quasi dieser Instanz, dass sie die Benutzeridentifizierung quasi korrekt gemacht hat und der User auch tatsächlich sich angemeldet hat. Also da ein Mensch vor einer Tastatur zum Beispiel sitzt und ein Passwort eingegeben hat oder ähnliches.

Stefan: Genau, darüber hinaus möchten die Anwendungen, die eben diesen Provider vertrauen auch eben gerne wissen: Wer ist denn das, der da am anderen Ende sitzt? Im Normalfall wollen auch Informationen auch über die angemeldete Person haben. Weiß nicht - eine E-Mail Adresse, einen Benutzernamen, einen Klarnamen, das ist wahrscheinlich unterschiedlich von Applikation zu Applikation, was sie wissen möchte. Aber sie braucht auch nicht nur die Sicherheit, da ist ein angemeldeter Benutzer, sondern möchte einfach auch wissen: Wer ist denn das?

Christoph: Gut, also SSO steht also für Single Sign On und vielleicht sollten wir nochmal kurz nochmal abgrenzen, zu welchem Bereich gehört das denn? Ist das jetzt eine Autorisierung? Und eine Authentisierung? Also… ODER eine Authentisierung? Und dann vielleicht nochmal näher darauf eingehen, welche verschiedenen Rollen in so einen SSO System den existieren.

Stefan: Über Autorisierung haben wir bis jetzt an der Stelle noch gar nicht gesprochen. Wir haben gesagt: Da gibt es jemanden, der möchte sicherstellen, dass Benutzer sich angemeldet haben und vielleicht wissen, wer das ist. Also insofern ist der Schwerpunkt sicherlich in dem Authentisierungsbereich zu suchen, es gibt abgestuft so ein bisschen den Autorisierungsbereich bei dem, dass ich sagte, die Anwendung möchte Dinge über die angemeldete Person wissen, da werde ich möglicherweise gefragt als Benutzer, wenn ich mich anmelde: Die Anwendung möchte deine E-Mail Adresse erfahren, möchtest du das zulassen, dass sie die E-Mail Adresse erfährt? Also da ist so ein Stückweit Autorisierung gelegentlich mit dabei, aber definitiv sind wir ganz klar im Authentisierungsbereich.

Christoph: Simon, das sagt das auch, der Nutzer gibt sein Passwort dann ein und alle möchten… Also alle Beteiligten, die wir gleich vielleicht noch klären, wollen dann wissen, ob das Passwort korrekt ist. Aber sind wir da überhaupt ans Passwort gebunden? Oder… Also das Passwort zwingt die Authentisierungsmethode oder…?

Simon: Ne, das war jetzt nur so ein Beispiel, wie man das üblicherweise kennt. Wie ich denn den Benutzer dann wirklich authentifiziere liegt letztendlich daran, wie das implementiert ist. Die Benutzeranmeldung kann auch so eine klassische Windows-Anmeldung sein zum Beispiel, die ich dann in anderen Applikationen verwenden kann. Das kann aber auch eine Passworteingabe mit einem zweiten Faktor sein, das kann eine Smartcard mit einem Kleinzertifikat sein, da gibt es keine Begrenzungen. Und ich würde auch sagen, die entsprechende Produktvielfalt da unterschiedliche Methoden anzubinden, die ist auch da. Aus einer Security Perspektive ist es halt wünschenswert, dass wir sowas wie ein Passwort-Reset irgendwie zentral managen können, dass, wie gesagt, die Benutzer wissen an welcher Seite geben sie ihr Passwort ein. Und wenn wir uns angucken wie Authentifizierung mit unterschiedlichen Systemen ohne Single Sign On aussehen in einem Enterprise-Umfeld, ist das halt eben ganz häufig, dass da irgendwie das LDAP angebunden ist wird halt eben über ein Bind geprüft, ob der Benutzer, der sich da gerade angemeldet hat an so eine Applikation korrekte Benutzername und Passwortkombination mit angegeben hat. Und dabei haben wir halt das Problem, dass über den Weg dann die Passwörter über die ganzen Applikationen laufen und sowas wollen wir vermeiden und eigentlich eher zentralisieren. Und dafür bietet sich dann eben Single Sign On an und da gibt es dann unterschiedlich Protokolle, die das quasi ermöglichen.

Christoph: Du hast jetzt schon eine ganze Reihe an Beteiligten genannt, die da in so einem System eine Rolle spielen können. Vielleicht können wir die mal aufschlüsseln sozusagen, welche generellen Rollen es denn so in einen Single Sign On System gibt. Und dann dazu überleiten welche Rollen denn da OpenID Connect bei spielt.

Simon: Die Begrifflichkeiten hängen halt natürlich so ein bisschen von dem Protokoll selbst ab. Wir haben sowas wie ein Relying Party zum Beispiel, das wäre in unserem Fall ein Service oder eine Applikation, die sich darauf verlässt, dass der Identity Provider die Identität des Users zur Verfügung stellt. So wie ich das richtig verstanden habe, in anderen Protokollkontexten, wie SAML, ist die Relying Party der Service Provider. Ich muss zugeben, ich kenne das hauptsächlich eben als Relying Party. Und darüber hinaus gibt es halt eben noch den User selbst, der sich irgendwo anmeldet. Ich würde sagen, das sind so die drei Beteiligten an so einem Anmeldeverfahren und wären so die grundsätzlichen Rollen, die wir da in dem Umfeld haben.

Christoph: Und welche Rolle spielt jetzt OpenID dabei? Übernimmt das mehrere Rollen? Ist das eine Rolle? Ist das so ein Software-Artefakt, das irgendwo dazwischen liegt? Oder was bedeutet dabei OpenID Connect?

Stefan: OpenID Connect ist ein Protokoll. Also keine direkte Rolle in diesem Kontext, sondern ist das Protokoll, wie ein Relying Party mit einem Identity Provider kommuniziert, wie sie Dinge erfährt. Und in OpenID Connect gibt es dann den OpenID Connect Provider, spezifischer als den Identity Provider. Also der OpenID Connect Provider ist dann der Identity Provider und ja, der Begriff der Relying Party taucht dort für denjenigen, der einfach wissen möchte, wer ist denn die angemeldete Person, auf.

Christoph: Und das heißt also, wenn ich so ein SSO -ystem bauen möchte, dann könnte ich OpenID Connect nehmen, das ist nur ein Protokoll und dann wüsste ich sozusagen, wie ich die einzelnen Sachen zusammenstecken müsste. Mal ganz einfach gesprochen. Jetzt habe ich schon öfter mal gesagt, OpenID, dann OpenID Connect, dann gibt auch noch irgendwie OpenID Foundation, von der ich mal gehört habe. Was ist denn mit den Begriffen? Unterscheiden die sich? Ist OpenID immer OpenID Connect? Also OpenID Foundation kann man sich ja vielleicht vorstellen, dass das irgendwie was Dahinterstehendes ist, dieses Protokoll weitertreibt. Aber bei OpenID und OpenID Connect wüsste ich die Unterschiede jetzt nicht.

Stefan: Das hat schon in den 00er Jahren glaube ich dieses Jahrtausends, wenn sogar nicht noch davor, Bestrebungen gegeben von verschiedenen Firmen, die miteinander kooperiert haben mit Anbietern von Webseiten wofür dann Weblogs erschienen sind, die man kommentieren konnte und so weiter, dass man dort SSO-Protokolle etablierte, damit Benutzer sich nicht ständig neu anmelden müssen. Und eine dieser Gruppen, die sich zusammengetan haben, war dann die OpenID Foundation und die haben ein Protokoll, das OpenID heißt, definiert. Zwischenzeitlich glaube ich auch eine zweite Version dieses Protokolls herausgegeben. Und das war eigentlich nicht so ein echtes Single Sign On, sondern so ein Multi Sign On. Das waren dann, die Identity Provider waren verteilt, dass ein komplett dezentrales System, bei dem zwischen Relying Party und Identity Provider beinahe ad hoc ausgehandelt werden konnte, dass die miteinander Geheimisse austauschen und man sich anmelden konnte. Das heißt ich als Benutzer konnte ich entscheiden, wer ist denn mein OpenID Provider? Und dann der Seite, bei der ich ein Kommentar möchte, einen URI geben, der meinen OpenID Provider identifiziert hat und dann wurde ein Log In Mechanismus durchgeführt. Aber gerade dieser dezentrale Teil war ein Stück weit eine Stärke, aber auch ein Stück weit eine Schwäche des Protokolls, weil dann es schwierig war den OpenID Providern auch zu vertrauen, zu glauben, dass die tatsächlich jetzt nicht lügen, wenn sie sagen: Der Benutzer ist Stefan und der hat sich gerade angemeldet. Das sich nicht irgendjemand für mich ausgeben könnte. Der könnte meine Identität vielleicht nicht übernehmen, aber zumindest E-Mail-Adresse fälschen oder sowas in dieser Form. Also sagen: Das passt zu der E-Mail-Adresse von Stefan. Sodass dann Nachfolgeprotokolle gesucht worden sind, bei denen es dann wirklich nur die eine sehr vertrauenswürdige Quelle gibt, wo wir zu Single Sign On hinkommen. Und da haben sich einige Kandidaten abgebildet und im Endeffekt ist OpenID Connect von der OpenID Foundation weitergetrieben wurden, basiert aber technisch auf ganz anderen Dingen, nämlich im Wesentlichen auf einem Protokoll, das Facebook entwickelt hat: Facebook Connect. Das ein von Facebook entwickelter Aufsatz auf OAuth 2.0 ist/war und das ist dann innerhalb der OpenID Foundation weiterentwickelt worden zu dem was wir heute als OpenID Connect kennen. Aber viele der Ideen, die heute in OpenID Connect stecken, waren schon in Facebook Connect drin.

Simon: Genau, um OpenID vielleicht ein bisschen noch einzuordnen: Es ist ja nicht so, dass es vorher keine Single-Sign-On-Protokolle gegeben hat. Wir haben sowas wie Kerberos, es gibt auch SAML, aber wo man das relativ häufig dann gesehen hat war zum Beispiel bei unterschiedlichen Blogs. Das war halt auch in den 00er Jahren dann sehr populär, da hat dann jeder gebloggt. Und natürlich möchte ich Kommentare unter so einem Post vielleicht nur von irgendwie Leute sich mal vorher registriert haben. Die sollen sich nicht alle bei meinem Blog anmelden, sondern theoretisch reicht es ja, wenn die eine Identität haben und eben mit dieser Identität dann quasi authentifiziert unter den Beiträgen posten können. Und da hatte OpenID dann halt seine Stärke, weil ich konnte irgendwo meinen OpenID Provider wählen und den konnte ich dann an den unterschiedlichen Stellen halt eben frei verwenden. Aber so wie Stefan das eben gesagt hat, der Fokus dabei ist halt so ein bisschen, eigentlich möchte ich in einem geschlossenen Applikationskreis ja nicht jedem Identity Provider vertrauen, sondern es geht mir ja darum, dass es da eine Instanz gibt, der ich stärker vertraue und eventuell gibt es noch eine zweite Instanz, die an irgendeiner anderen Stelle steht, die man da mit anbinden könnte. Aber da ist dann halt eben letztendlich, das entsprechend kompatibel hinzubekommen, die Stärke bei dem Facebook Connect gewesen, was das dann halt eben auf eine in Anführungszeichen modernere Art und Weise löst. Wir haben da dann halt eben auch OAuth gehabt und das Problem bei OAuth ist halt eben einfach, ich habe da keine Anmeldung. Wir delegieren halt eben Third Üarty Access zu einer Ressource und so Dinge wie eine Benutzer Session existiert da gar nicht. Ich kann mich auch nicht anmelden und wieder ausloggen, weil es dafür nicht vorgesehen ist. Und deswegen reicht mir OAuth 2.0 alleine nicht und alle Firmen, die irgendwie OAuth 2.0 eigentlich als Authentifizierung nochmal benutzt haben, haben da noch wahnsinnig viel drum rum gebaut. Wir erinnern uns, das ist ein Framework, damit baue ich quasi diese Delegation. Und wenn ich da jetzt sowas als Benutzeranmeldung verwenden möchte, dann muss ich da halt eben noch etwas drüber bauen und Facebook Connect war dann eben der Überbau, der sich da an der Stelle in der Community auch durchgesetzt hat.

Christoph: So, das heißt dann jetzt im weiteren Verlauf werden wir dann, auch wenn wir dann manchmal nur OpenID sagen, über OpenID Connect sprechen. Und im Bereich OAuth, wo das ja drauf aufbaut, dann auch über OAuth 2.0. Dieses Protokoll ist ja auch, hat ja auch eigene Specs dabei, also die OpenID Connect Specs. Da würde ich dann gerne mal drüber sprechen, woraus denn so das besteht und was so die wichtigsten Punkte daraus sind? Also wo sich dieses Protokoll zum Beispiel von OAuth 2.0 unterscheidet. Es gibt da mehrere Specs, ich würde dann sagen, wir fangen einfach mal mit der Core Spec an. Was haben wir denn da mit in der Core Spec? Was ist denn da mit definiert alles? Also alles Wichtigere.

Stefan: Im Wesentlichen baut OpenID Connect auf dem Flows von OAuth 2.0 auf. Die beiden Dinge, die bei OAuth definitiv fehlen sind zum einen die Sicherheit, da ist gerade ein Benutzer angemeldet. Weil wir mit Refresh Token oder sonstigen Dingen einfach auch Token ausstellen könnten, die überhaupt nicht voraussetzen, dass gerade interaktiv ein Benutzer vor dem Rechner sitzt. Und der andere Teil, der fehlt ist eben tatsächlich das Wissen, wer ist denn da angemeldet? Weil das Token, das in OAuth ausgestellt wird, diese Information in der Regel nicht enthält. Sondern nur enthält, was darf Derjenige, der mir dieses Token gerade vorzeigt. Die OpenID Connect Spec setzt im Wesentlichen auf den Authorization Code Grant Flow auf, es gibt gar keine OpenID Connect Spezifikation für Client Credentials oder Ressource Owner Password Grant Flows. Es gibt das für den Implicit Flow und das ist ein Hybrid zwischen dem Authorization Code Grant und dem Implicit Flow als zusätzlicher Flow definiert wurden bei dem… Der heißt dann auch Hybrid Flow. Bei dem praktisch ein JavaScript-basierter Client doch ein Token in die Hand bekommt und auch ein Refresh Token in die Hand bekommt, und zwar das direkt über einen Aufruf des Token-Endpunkts. Also genau die Dinge bei der wir in der OAuth 2.0 Folge gesagt haben, in 2.1 fliegt der implict Flow raus, weil der da unsicher ist. Der Hybrid Flow ist da eher der vielleicht ein wenig sichererer Weg an der Stelle. Wir haben den normalen OAuth 2.0 Authorization Code Grant Flow und bekommen ein zusätzliches Token. Wir müssen vielleicht nochmal über die Rollen kurz sprechen. Also in OAuth hatten wir den Authorization Server, der hier offensichtlich der OpenID Connect Provider ist und wir hatten Client und Ressource Server an der Stelle. Der Client war also derjenige, der irgendetwas von den Ressource Server möchte und der Ressource Server Derjenige, der im Namen des angemeldeten Benutzers irgendwelche Ressourcen zur Verfügung stellt. Und da ist die Verteilung nicht ganz klar eigentlich auf den ersten Blick. Wer von den beiden soll jetzt die Relying Party werden? Und in dem Bereich OpenID Connect hat man sich entschieden, dass das was in OAuth 2.0 der Client ist, die Relying Party wird und der Ressource Server schlüpft eigentlich so ein Stück weit in den Authorization Server, also in den OpenID Connect Provider, hinein. Denn der OpenID Connect Provider hat einen zusätzlichen Endpunkt, den sogenannten User Info Endpunkt. Den kann ich mit dem Access Token, den ganz normalen OAuth 2.0 Access Token, das ich bekommen habe, aufrufen und bekomme Informationen über den angemeldeten Benutzer. Also der OpenID Connect Provider stellt selber als Ressource Server so eine Ressource zur Verfügung, in der ich Profildaten über den angemeldeten Benutzer abholen kann. Das ist der eine Teil der neu ist. Der zweite ist, dass der Relying Party, also dem Client in OpenID Connect sprich in OAuth 2.0, ein zusätzliches Token ausgestellt werden kann, wenn der Client das möchte. Das ID Token. Bekommt nach wie vor das normale OAuth 2.0 Access Token, das aber nicht für den Client gedacht ist in OAuth 2.0 von dem Gedanken her. Während das ID Token tatsächlich für die Relying Party, für den Client gedacht ist. Und darin stehen auch Informationen über den Endbenutzer, die… Welche Informationen genau, da werden wir sicherlich gleich nochmal im Detail drüber sprechen. Aber im Wesentlichen bekomme ich ein zweites Token, das für die Relying Party gedacht ist. Das erste Token, das Access Token ist eigentlich ursprünglich nur dazu gedacht sich beim User Info Endpoint Profilinformationen abholen zu können.

Simon: So mal das nach der OAuth Spec ja gar nicht definiert ist, was da drinsteckt. Also wenn ich das jetzt Protokollkompatibel irgendwie implementieren möchte, darf eben in diesem Access Token beliebiges drinstehen. Das hilft mir natürlich nicht weiter, wenn ich eigentlich nicht alles selbst programmieren möchte, sondern vielleicht eben Software installiere, die ein OpenID Connect Identity Provider ist und dann immer wieder neu rausfinden muss: Wie ist denn jetzt genau das Format in diesen Token? Und wie ist denn der Key wo der Benutzername drinsteht? Oder ähnliches. Das ist in OAuth alles nicht näher spezifiziert, sondern das Token ist eigentlich für den Client an der Stelle komplett unsparent und er kann es halt eben an diesen User Info Endpoint tauschen gegen zuverlässige Benutzerinformationen. Die OpenID Connect Spec führt eben ein zusätzliches Token ein und an der Stelle sollten wir es so ein bisschen vielleicht erwähnen: OAuth 2.0 und OpenID Connect sind natürlich unterschiedliche Standards und Spezifikationen mit anderen Working Groups dahinter, trotzdem ergänzen die sich gegenseitig. Also es sind ganz viele Dinge, die zuerst in OpenID Connect umgesetzt wurden, dann später in die OAuth Spec gewandert. Und die OAuth Spec selbst ist ja genau so flexibel gestaltet, dass man sie halt eben erweitern kann. Und nicht jede Erweiterung macht irgendwie Sinn oder ist vorhanden, aber das was Stefan eben erwähnt hat mit dem Hybrid Flow zum Beispiel, das ist dann einfach eine Erweiterung um zusätzlichen Flow, was da die Spec dann auch zulässt. Und wenn wir jetzt in das ID Token reingucken wollen, dann haben wir bei OpenID Connect halt den Vorteil, dass klar definiert ist in welchen Datenformat ist das denn eigentlich abgelegt? Also dass ist in dem Fall ein JWT Token und da dann halt klar definiert in welchem Feld oder in welchem… Was ist der Key, um den Benutzernamen rauszubekommen? Oder die E-Mail-Adresse oder das Geburtsdatum? Oder wann er das letzte Mal angemeldet war und alle Informationen, die ich da halt eben unterbringe.

Christoph: Was so ein JWT Token genau ist und wie das aufgebaut ist, da könne wir gleich nochmal drüber reden. Stefan sagt ja auch, dass wir nochmal gucken müssen was im ID Token steckt. Aber mich interessiert vor allem nochmal eins, um das für mich klar zu machen: Mit dem Access Token in OAuth hätten wir ja schon irgendeine Art von Autorisierung, dass wir mit diesem Access Token was machen. Das scheint mir jetzt nicht mehr so der Fall zu sein. Jetzt heißt es, das Access Token ist zwar noch da, wir wissen gar nicht was wir damit machen können, sondern wir haben jetzt ein ID Token. Aber ID Token ist doch noch keine Autorisierung für irgendetwas oder irre ich mich da?

Stefan: Dazu ist es auch nicht gedacht, genau. Das ID Token ist dazu da Informationen über den angemeldeten Benutzer zu liefern und vielleicht noch so ein bisschen Session Zusammenhang zu haben, Zusammenhalt zu haben. Also als erweiterte Identifikation der Benutzer Session zu dienen. Das Access Token ist nach wie vor da, aber das dient ausschließlich dazu den User Info Endpunkt aufzurufen. Da ist dann auch Delegation da: Ich erlaube der Relying Party Informationen über den Ressource Owner abzurufen. Also das ist schon nach wie vor vorhanden. Das ist so der eine Aspekt, ich hatte noch gesagt, der andere Teil, der so ein Stückweit fehlt in OAuth, ist die Sicherheit, da ist tatsächlich jemand interaktiv angemeldet. Da wird der Flow ein Stückweit erweitert, da werden zusätzliche Parameter definiert, die Authorization Code Grant Flow und auch im implicit und im Hybrid Flow benutzt werden können. Einer dieser Parameter steuert zum Beispiel, dass ich sage: Ich möchte in jedem Fall, dass der Benutzer sich neu anmelden muss. Also ich möchte, dass er, selbst wenn er am OpenID Connect Provider schon angemeldet war, der Benutzer das trotzdem nochmal tun muss. Und genau der umgekehrte Weg ist ebenfalls möglich, dass ich sagen kann: Ich möchte eigentlich gar nicht, dass der Benutzer eine Log In Maske zu sehen bekommt. Bitte schick den direkt wieder zu mir zurück mit dem Token drinnen oder mit dem Authorization Code, den ich gegen ein Token umtauschen kann. Falls das nicht möglich ist, sende mir bitte eine Fehlermeldung. Also da gibt es so Feingranulare Steuerungsmöglichkeiten dieser Redirect Interaktion. Und mit der habe ich die Möglichkeit zu sagen: Ich möchte unbedingt, dass der Benutzer sich anmeldet oder ich erlaube höchstens, dass es dann ein anderer Parameter, dass der Benutzer… Also ich möchte, dass er sich innerhalb der letzten 15 Minuten einmal angemeldet hat oder sowas in dieser Form. Dass ich also so bestimmte Obergrenzen festlegen kann, wie lange darf denn das her sein, dass der Benutzer das letzte Mal interaktiv gesehen worden ist.

Christoph: Diese Informationen stecken dann auch im ID Token? Oder wo finde ich die?

Stefan: Genau, da stecken sie drinnen, wenn die entsprechenden Claims angefragt worden sind. Jetzt kommen wir dann irgendwo dahin, dass wir tatsächlich über den Inhalt des ID Tokens sprechen müssen.

Christoph: Dann tun wir das doch einfach und ihr erklärt uns mal, was denn da drinsteckt. Jetzt hast du ein Wort genannt: Claims. Ein anderes was ich immer höre ist auch noch Scopes. Da könntet ihr vielleicht mal kurz sagen, was der Unterschied dazu ist und was da überhaupt drinnen ist.

Simon: Also ein Claim ist erstmal nur eine Aussage, die des Identity Providers über den Benutzer. Der claimed, dass diese Information zutreffend ist. Und wir kennen das ein Stückweit von SAML her, da nennt sich das Assertion, da wird der Service Provider eine Zusicherung machen, dass diese Information über den Benutzer korrekt ist. Und an der Stelle hat man die Idee, die es bei SAML auch schon gab, quasi nur auf ein anderes Format übertragen. Ich habe eben jetzt kein großes XML mehr, sondern ich habe eben ein JSON Format und darin stehen halt Key Value Paare und das sind Aussagen über die Benutzer. Das ist erstmal ein Claim. Und Scope hängt so ein bisschen davon ab, wie man das jetzt definieren möchte. Also OAuth 2.0 definiert Scopes erstmal auch wieder mehr oder weniger als String, da hängt nichts bestimmtes dran, ein Client kann beliebige Scopes anfragen. Und OpenID Connect definiert jetzt speziell im OpenID Connect Scope gültige Erweiterungen. Das heißt, wenn wir OAuth 2.0 Requests sehen, haben die normalerweise auch OpenID Connect als zusätzliches Scope, was angefordert wird mit drin. Und gleichzeitig hat man sich gesagt: Okay, es gibt immer, wahrscheinlich, eine ganze Gruppe an Claims, die mich interessieren. Zum Beispiel sowas wie personal info von dem Benutzer. Und da habe ich natürlich nicht nur einen Claim, sondern gleich mehrere. Oder ich möchte eigentlich wissen: Wie ist denn die E-Mail-Adresse? Und hat dieser Benutzer diese E-Mail-Adresse irgendwann mal verifiziert? Und diese Dinge sind einfach nochmal zusammengefasst innerhalb von einem Scope. Das heißt, wenn ich als Client wissen möchte: „Die ist die E-Mail-Adresse des Benutzers und hat er diese irgendwann mal verifiziert? Dann kann ich zusätzlich einfach das Scope E-Mail anfordern und kann mir sicher sein, die Antwort im ID Token enthält dann auch wirklich die entsprechenden Einträge, die ich da erwarten würde.

Christoph]: Also zusammengefasst könnte man einfach sagen: Ein Scope ist eine Gruppe von Claims, die irgendwo definiert wurde. Zum Beispiel in der Spec. Du sagtest jetzt, OpenID Connect Spec definiert auch schon solche Scopes. Welche Claims stecken denn dann standardmäßig da drin?

Simon: Nur um da nochmal deutlich zu sagen: Eine Gruppe von Claims kann in Form von einem Scope abgebildet sein, aber nicht jeder Scope, Beispiel OpenID Connect als ein Scope und irgendwelche andere Erweiterungen, sind automatisch eine Gruppe an Claims.

Stefan: Genau, also zu einem haben wir in der OpenID Connect Spec Scope OpenID, die haben dann Connect irgendwie hinten runterfallen lassen. Mit dem identifiziere ich diesen OAuth 2.0 Flow, den ich anstoße, überhaupt erst als einen mit dem ich OpenID Connect sprechen möchte. Da sind dann noch gar keine Claims wirklich drangebunden. Dann gibt es Scopes E-Mail, Profile, Adresse, noch so ein paar andere mit denen ich eben Gruppen von Claims adressieren kann, die sind dann in der Spezifikation relativ klar ausdeklariert. Das sind zwei Handvoll, ein bis zwei Handvoll Scopes, die da vordefiniert sind. Aber Scopes gibt es natürlich auch nach wie vor darüberhinausgehend aus dem OAuth 2.0 Bereich kommt, also man könnte noch mehr Scopes anfragen, neue erfinden. Und zusätzlich bietet OpenID Connect noch eine Erweiterung, bei der man beim Authorization Request einen Parameter mitgeben kann, indem man in einer relativ komplizierten JSON Struktur beschreiben kann, welche Claims man in ID Token sehen möchte und welche davon verpflichtend drin sein möchten, man möchte lieber gar kein Token haben als ein Token ohne diese Claims. Ich muss allerdings zugeben, dass ich das bisher eher als exotischen Anwendungsfall wahrgenommen haben und eigentlich bisher nicht gesehen habe, dass das aktiv genutzt wird.

Christoph: Gut, und wie würde ich dann solche weiteren Scopes und Claims anfragen? An welcher Stelle passiert das? Passiert das am Anfang, wenn ich so einen Flow starte? Oder kann ich die auch nachträglich nochmal zusätzlich anfordern, wenn ich zum Beispiel sage: Ich bin jetzt an einer Stelle, da brauche ich jetzt nicht noch mehr Informationen. Fordere ich dann ein neues ID Token an? Oder wie funktioniert das?

Stefan: Scopes in OAuth 2.0 funktionieren, zumindest auf einem theoretischen Level ja so, dass der Benutzer dem zustimmt. Auch hier würde ich Scopes benutzen und als OpenID Connect Provider den Benutzer fragen: Der Service da hinten möchte deine E-Mail-Adresse haben, darf er das? Und dem Gedanken folgend heißt das, die Scopes gebe ich an bevor überhaupt die Anmeldung des Benutzers geschieht und der Benutzer muss in diesem Kontext bei OpenID Connect Provider dem zustimmen, dass bestimmte Informationen überhaupt an die Relying Party herausgegeben werden können. Ich kann nicht in Nachhinein noch einfach davon ausgehen, dass Consent da ist. Tatsächlich ist es so, dass in vielen Zusammenhängen, vor allen Dingen so ein Enterprise-Umfeld, wir annehmen, dass diese Zustimmung implizit gegeben ist und dann der Benutzer gar nicht danach gefragt wird. Aber wenn wir uns öffentliche OpenID Connect Provider anschauen, dann passiert das durchaus, dass solche Nachfragen passieren. Also wenn ich das GitHub API als Entwickler benutze, wo OpenID Connect verwendet wird und da vergangenen Wochenende noch irgendeinen Travis CI Zugriff für eines meiner Repositories erlaubt, dann fragt mich GitHub: Erlaubst du Travis CI den folgenden Zugriff, nämlich das Auflisten deiner Repositories oder sowas. Also das muss ich dann tatsächlich dem explizit zustimmen und das sind dann Scopes, die GitHub spezifisch definiert hat und die Travis kennt und dann anfordert, sodass die so zusammenspielen können. Das heißt ich erweitere das Vokabular der Scopes vielleicht spezifisch für einen OpenID Connect Provider, um auch an zusätzliche Claims zu kommen oder um ein Access Token zu erhalten, das noch zusätzliche Dinge tun darf.

Christoph: Wenn ich das jetzt mal zusammenfasse, wo wir jetzt gerade stehen, heißt das: OpenID Connect setzt erstmal auf OAuth 2.0 auf und der Unterschied dabei ist, dass ich neben dem Access Token und eventuell dem Refresh Token noch ein ID Token bekomme. Und in dem ID Token stecken dann halt Scopes und Scopes sind vereinfacht gesagt eine Zusammenfassung von Claims. Also zum Beispiel: Das ist die E-Mail-Adresse des Users und das ist sein Vorname, sein Nachname, Geburtsdatum, was auch immer in so einem Claim drinstecken kann. Und bevor ich die aber bekomme, müsste der User erstmal bei der Anmeldung, also wenn er dann bei dem Authorization Server ist, erstmal seinen Consent geben, dass das alles an den Anfragenden weitergeleitet werden darf. Habe ich das so richtig verstanden, dass das sozusagen die Core Spec umfasst?

Stefan: Im Wesentlichen ja. Die Scopes selber würden im ID Token als Scopes gar nicht auftauchen, sondern das Ergebnis der Auswertung dieser Scopes in Form von Claims stehen drin. Die Scopes selber, die ursprünglich angefragt wurden sind, die würden wahrscheinlich eher im Access Token versteckt sein, als dass sie im ID Token auftauchen.

Christoph: Okay. Jetzt gibt es ja noch weitere Bestandteile, die OpenID Connect umfasst. Also da gibt es ja noch eine ganze Reihe von Specs, die so drum herum sind um diese Core Spec. Wollen wir die doch noch durchgehen und versuchen zu erklären. Also da gibt es zum Einem mal, als erstes fällt mir ein die Discovery Spec. Was verbirgt sich denn dahinter?

Simon: Immer dann, wenn die komplette Infrastruktur nicht in einer Hand ist, sondern OpenID Connect ist ein Stückweit durch das Netz auch gebaut, ist natürlich die Frage: Wie finde ich die ganzen Endpunkte? Wo finde ich denn eigentlich bestimmte OpenID Connect Funktionalität? Wie sieht die URI dazu aus? Und alle diese Informationen möchte ich möglichst einfach zur Verfügung stellen. Und da gibt es einfach den Discovery Teil, der im Wesentlichen relativ simpel definiert, dass es halt eben Well-Known URIs gibt, also das klassische im Pfad ist halt eben Well-Known, benutzt. Und dahinter gibt es den OpenID Connect spezifischen Config File und wenn ich halt eben diese File aufrufe, habe ich als Partizipierender in dem Protokoll dann die Informationen welche Endpunkte ich am Identity Provider halt entsprechend aufrufen kann und wie ich die erreiche. Und bekomme allgemein die Informationen eben über die Config von meinem Server.

Stefan: Also im Wesentlichen ein standardisiertes Metadatendokument, das dem OpenID Connect Provider die Dinge, die er kann, die Dinge, die er anbietet, beinhaltet. Darin steht zum Beispiel auch möglicherweise eine Liste von Scopes, die der OpenID Connect Provider unterstützt, welche Claims man anfragen könnte. Solche Dinge können in einem solchen Discovery Dokument noch mit drinstehen.

Christoph: Das heißt sowas brauche ich dann, wenn ich meinen Client konfigurieren will und dann nicht alles irgendwie hart reinkodieren muss über, wer weiß woher ich die Informationen kriege, sondern ich kann dieses Dokument nehmen, abrufen und dann die entsprechende Konfiguration vornehmen. Ich weiß, wo die URLs sind, ich weiß welche Scopes ich zum Beispiel anfragen kann, welche Erweiterungen unterstützt werden und so weiter und so fort.

Simon: Genau, idealerweise nimmst du nicht das Dokument und lädst runter und hinterlegst das, sondern du gibst halt einfach nur die URL an und wenn sich dann etwas an der Konfiguration eben ändert, bekommt der Client das auch mit, kann das Ergebnis natürlich cachen sinnvoller Weise. Genau.

Christoph: Damit kann man ganz gut überleiten, es gibt nämlich auch eine Spec die heißt ‚Dynamic Client Registration‘. Ich glaube die wird ja wahrscheinlich im ähnlichen Zusammenhang dazu stehen.

Stefan: Nun ja, das ist, weiß ich nicht, vielleicht so ein Stück weit der Gegenpart zu Discovery. Also wie kommt ein Client überhaupt in den Zustand, dass er mit dem OpenID Connect Provider sprechen darf und von ihm Token erhält? Da ist also ein Protokoll mit den ein Client sich selber registrieren kann, dann muss, dass haben wir in OAuth 2.0 Podcast schon besprochen gehabt, der OpenID Connect Provider muss zum Beispiel den Redirect URI kenn, wohin schicke denn nachher die Antwort mit dem Authorization Code oder mit dem Token, je nachdem welchen Flow ich benutze? Und so ein paar andere Dinge muss so ein Client einfach auch über sich bekannt machen, was er denn unterstützen könnte und hier gibt es dann eben eine Spezifikation, mit der man wohldefinierte Dokumente austauscht mit den Metadaten, um an die Informationen zu kommen. Das heißt nicht zwangsläufig, dass ein OpenID Connect Provider, der da in der Dynamic Client Registration unterstützt damit offen für beliebige Registrierungen von Clients ist, sondern das ist das Protokoll, mit dem es dann überhaupt möglich ist, dynamisch Clients zu registrieren. Aber es ist trotzdem so, dass man sich nur registrieren kann beispielsweise, wenn man einen dafür freigegebenen Code oder ein Geheimnis erhalten hat, damit man dann die Metadaten dynamisch anliefern kann, die notwendig sind.

Simon: Kann auch eine IP-Range quasi sein, wenn man da sich irgendwie einen Use Case zusammenbauen möchte mit den hundert Kubernetes Pods, die auf so einer eigenen Plattform laufen. Dass mal halt eben die Pods, die an der Stelle laufen, dass die automatisch halt eben entweder das Token oder Zugriff darauf haben und sich dann eben selbst als Client registrieren können und nicht irgendwer die hundert Tickets abarbeiten muss.

Christoph: Das heißt also, das Discovery ist für den Client dazu da, um sich sozusagen dynamisch oder selbstständig konfigurieren zu können davon und die Dynamic Client Registration ist die Gegenseite, damit sich der Client der Serverseite auch bekannt machen kann und dann vielleicht entsprechende Konfigurationen vorgenommen werden können, wie zum Beispiel die Call-Back URLs oder ähnliches.

Simon: Genau und hier wird man auch die… also, findet man auch das Beispiel wo die Specs so ein bisschen ineinanderfließen. Soweit ich das in Erinnerung habe, ist eben Discovery und Dynamic Client Registration zuerst im Umfeld von OpenID Connect spezifiziert wurden und danach dann aber auch in die OAuth 2.0 Spec gewandert. Das heißt, wenn ich dann auf der Suche bin, werde ich das entsprechende Pendant auch für OAuth finden.

Stefan: Die sind nicht exakt identisch, weil es bestimmte Dinge gibt in dem Discovery Dokument für OpenID Connect, die OpenID Connect spezifisch sind. Dafür gibt es Flows in OAuth 2.0, die in OpenID Connect nicht benutzt werden, für die braucht man aber vielleicht auch Konfigurations-Wissen, die stecken dann nur in der OAuth 2.0 Discovery Spezifikation drinnen. Und die URIs sind verschieden, was unter Umständen dann auch bedeutet, dass wenn man einen Client konfigurieren möchte, der erst den einen und dann den anderen ausprobiert, um zu gucken welche von den beiden Spezifikationen denn gerade unterstützt wird. Und auf der anderen Seite für einen Provider vielleicht auch bedeutet, dass er die Endpunkte unter beiden URIs anbietet und eigentlich das gleiche Dokument an beide zurückliefert. Strukturell sind die aber sehr, sehr stark aneinander angelehnt.

Christoph: Einer von euch beiden hatte ja schon am Anfange mal angedeutet, dass es auch irgendetwas mit Sessions zu tun hat, OpenID Connect. Oder dass es sowas wie eine Session gibt. Dafür gibt es ja scheinbar auch eine ganze Spec ‚Session Management‘ und damit vielleicht auch einen Zusammenhang gibt es die Logout Spec, also halt wie man eine Session beendet. Könnt ihr darauf nochmal kurz eingehen, was sich hinter der Session Management und der Logout Spec verbirgt?

Simon: Generell muss man natürlich sagen: So eine User Session ist ja ein Stück weit eigentlich ein fachliches Objekt. Völlig unabhängig davon wie lange irgendwelche technischen Sessions, was ein Cookie angeht oder sowas, läuft, gibt es halt den Zeitpunkt, ab dem der Benutzer angemeldet ist und es gibt den Zeitpunkt, an dem der Benutzer nicht mehr angemeldet ist. Und alles was dazwischen passiert, passiert normalerweise im Kontext von so einer User Session. Und wenn wir OAuth 2.0 betrachten, da sehen wir halt schon einen der Unterschiede: Da gibt es keine Session, weil wir haben keine Benutzeranmeldung. Und wenn ich OpenID Connect benutze, können wir davon ausgehen, dass der Benutzer eben angemeldet ist, aktiv, zu einem gewissen Zeitpunkt. Wenn das nicht der Fall war, können wir das halt entsprechend auch nochmal abfragen oder können eine Anmeldung über bestimmte Mechanismen erzwingen und ab diesem Zeitpunkt besteht eben diese User Session und dann muss man anfangen sich Gedanken drüber zu machen: Was passiert eigentlich bei einem Logout? Also wir haben jetzt über Single Sign On gesprochen oder Single Log On. Jetzt ist die Frage, wenn der Benutzer einer Anwendung auf Logout klickt, ist das ein Single Log Out, das heißt ist er überall abgemeldet? Oder ist das nur die Session in der spezifischen Applikation? Und damit muss man in irgendeiner Art und Weise umgehen. Und OpenID Connect hat selbst verschiedene Mechanismen definiert, wie ich eben mit so einer Session umgehen kann. Was passiert damit, wenn der Benutzer inaktiv ist? Läuft die irgendwann aus oder möchte ich vielleicht irgendwie aktiv als Applikation den Identiy Provider darüber benachrichtigen, dass da halt irgendwie Benutzeraktivität gerade stattfindet? Und das sollte idealerweise ja so passieren, dass ich davon nichts mitbekomme. Das heißt ich als Anwendung möchte eigentlich nur wissen: Hat der User jetzt eine gültige Session oder nicht? Und das wird eben in diesen Session Management Teil geschrieben. Das Problem damit ist, die Umsetzung für dieses keep alive ist… Ja, wie bezeichnen wir das in… Also ich würde es als ‚Gebastel‘ eher bezeichnen, gelöst zum Beispiel, indem einfach im Client iFrame eingebunden wird, was dann so eine permanente Verbindung mehr oder weniger zum Identity Provider offenhält und da sozusagen so einen keep alive hinschickt. Das Problem damit ist, dass sich inzwischen die Browser auch ein bisschen verändert haben, da kann Stefan auch noch ein bisschen was dazu erzählen glaube ich. Dass wir einfach nicht mehr so einfach dieses keep alive über das Einbinden von einem iFrame überhaupt lösen können. Von daher ist die Frage: Also ja, Sessions in der Form haben wir, aber Teile von der Spec werden halt eben in aktuellen Browsern ziemlich schwer zu implementieren sein. Vor allem wenn da noch weitere Netzwerkinfrastruktur dazukommt, wie irgendwelche reverse proxies und was da alles noch dabei hinter hängt. Da wird es dann halt irgendwann schwierig.

Stefan: Ja, also die Session Management Spec selber ist, wenn ich es richtig in Erinnerung habe, sogar eine, die im Endeffekt zwei iFrames, die miteinander kommunizieren verlangt. Der eine bekommt die Informationen vom OpenID Connect Provider, bekommt die Information, ob der Benutzer überhaupt noch angemeldet ist am OpenID Connect Provider, beziehungsweise ein Event, wenn er nicht mehr angemeldet ist. Und dann kommuniziert er mit einem anderen iFrame, der dann mit der Relying Party kommuniziert und der dann das Ergebnis mitteilt, die dann darauf in irgendeiner geeigneten Form reagieren kann. Und hier haben wir in neuen Browsern sehr häufig das Problem, dass eingebettete iFrames, die einen Zustand auf irgendeinen third party Server haben, eigentlich verdammt stark nach Tracking von Benutzern riecht und deshalb die Browser sich zunehmend gegen solche Mechanismen wehren. Also Beispiele sind, dass keine Cookies mehr gesendet werden, also so richtig gar keine mehr. In einem bestimmten Kontext hat man segmentierte Cookies, also das vielleicht noch davon abhängt, welche Relying Party jetzt den iFrame zum OpenID Connect Provider aufgemacht hat, dass es unterschiedlich Sätze von Cookies hat. Oder dass eben bei anderen Browsern gar keine Cookies mehr mitgesendet werden. Auch local storage, die Alternative für Clientseitigen Zustand, wird innerhalb solcher third party iFrames nicht mehr sauber unterstützt. Insofern ist dieses Konstrukt, das sich immer schon ein bisschen komisch angefühlt hat, auch eines, dass technisch heute wahrscheinlich in vielen Browsern gar nicht mehr funktioniert. Im Session Management, in der gleichen Spezifikation selber steckt auch noch ein Teil der Logout Fähigkeiten. Nämlich der Weg, wie eine Relying Party, bei der sich Benutzer abgemeldet haben, den OpenID Connect Provider mitteilen kann, dass sich der Nutzer abgemeldet hat. Also das ist im Wesentlichen ein Logout URI, den der OpenID Connect Provider anbietet, an den man einen post schickt mit der Identität des ID Tokens, das ursprünglich mal ausgestellt worden ist. Und da kann man dann hinten drauf nochmal einen anderen Redirect URI angeben, sodass anschließend also der OpenID Connect Provider merkt sich: Gut, Benutzer ist abgemeldet. Macht einen Redirect zurück auf irgendeine ‚Schön, dass Sie hier waren. Besuchen sie uns bald wieder‘ Abschiedsseite bei der ursprünglichen Relying Party. Hier haben wir also den Mechanismus, wie kann eine Relying Party, die fachlich gerne möchte, dass ein Logout bei der Relying Party gleich ein Logout aus dem kompletten Single Sign On Verbund ist, dass zumindest bis zum OpenID Connect Provider hinbekommt? Die anderen Logout Specs, die es da noch gibt, sind der umgekehrte Weg. Der OpenID Connect Provider weiß der Benutzer ist abgemeldet und hat sich gemerkt für welche Relying Parties habe ich denn mal Token für diese aktive Benutzersession ausgestellt? Und teilt allen diesen Relying Parties mit, dass der Benutzer jetzt nicht mehr da ist. Da gibt es zwei Geschmackrichtungen. Die eine funktioniert über den Browser des Benutzers. Im Wesentlich funktioniert auch das wieder iFrames, da wird also zu allen möglichen Relying Parties ein iFrame geöffnet, um denen mitzuteilen: Benutzer ist weg. Hat möglicherweise die gleichen technischen Limitationen, die wir eben schon für das Session Management angesprochen haben, dass es in modernen Browsern schwierig wird third party iFrames überhaupt mit Daten zu bestücken. Die andere Spezifikation ist eine, wo es dann wirklich Server zu Server Kommunikation bedeutet. Ist die back-channel logout Spezifikation bei der der OpenID Connect Provider einen HTTP Endpunkt, den die Relying Party anbietet, direkt ohne den Browser und dann möglicherweise Firewalls im Weg stehen könnten. Oder andere Netzwerkprobleme auftreten, dass man irgendjemanden erlauben muss diesen Zugriff zu machen, aber nicht jeden beliebigen Service da aus dem Internet erlauben möchte so zu tun, als wäre da jemand abgemeldet.

Simon: Also es ist halt wichtig so eine Session dann auch wirklich aktiv zu terminieren. Wir machen das ganze Theater mit dem Logout ja nicht, weil irgendwem langweilig ist, sondern das ist eigentlich ein ganz elementares Security Feature. Ich möchte auf Logout klicken und dann ist es völlig egal wer irgendwann mal in dieser Kommunikation da Man in the Middle gespielt hat und irgendwelche Login Tokens oder Credentials abgefangen hat. In dem Moment müssen diese Login Credentials eigentlich halt eben ungültig sein. Und jetzt kann man da ein bisschen drüber diskutieren: Wie lange darf denn eigentlich dieser Zeitverzug sein? Ich könnte ja durchaus meine Tokens haben, die nach 15 Minuten sowieso ablaufen und ich sage halt eben: Gut, wenn der Benutzer auf Logout klickt, dann gehen wir das Risiko ein, dass da jemand, der diese Credentials abgefangen hat, nach 15 Minuten sich an der Anwendung anmelden kann. Aber das muss ich halt eben beurteilen, in was ein Umfeld bewege ich mich hier? Wenn wir an das Online Banking denken, da läuft die Session automatisch ab, wenn ich irgendwie 5 Minuten oder 10 Minuten lang nichts auf der Homepage mache. Und da ist es natürlich irgendwie elementar wichtig, dass ich diesen Mechanismus habe, der meinen Back-End noch mitteilen kann: Hey, der Benutzer ist jetzt wirklich aktiv abgemeldet. Und das ist halt wieder der Teil, den ich mit einem…, wenn die Frage kommt: Warum kann ich ein AuthN nicht mit OAuth 2.0 machen? Das sind die Dinge, die in dem Moment von einem echten Single Sign On Protokoll auch tatsächlich abgedeckt werden.

Christoph: Also ich fasse das nochmal für mich zusammen, wieder in kurz und knapp: Also Session Management und Logout Spec, die kümmert sich halt darum das Problem zu lösen, dass ich gerne in meinen Anwendungen wahrscheinlich irgendwas wie eine Art Session habe. Das Problem aber ist, dass ich ein verteiltes System habe und da nicht jeder immer mitbekommt wann so eine Session überhaupt anfängt, beziehungsweise vielleicht auch schlimmer, wie Simon gerade gesagt hat, dass ich nicht immer mitbekomme wann diese Session auch endet. Und wir sind jetzt im Status, dass nicht mehr alles, das wir in diesen Sessions definiert wurde, gerade so keep alive, was dazu da ist, um zu wissen: Ist diese Session denn jetzt noch gültig oder nicht? Oder auch das Logout in der konkreten Implementierung, die da vorgeschlagen ist, mit aktuellen Browsern, wegen der iFrame Problematik nicht mehr so richtig funktioniert. Ist das soweit… Habe ich das soweit richtig verstanden?

Stefan: Ich glaube schon.

Christoph: Ja. Dann hätte ich zwei Sachen, die ich da noch gerne besprechen würde. Das eine ist: So iFrames und Implementierungsdetails sind natürlich ein guter Übergang zu den sozusagen low-level Bausteinen, auf denen dieses Protokoll so basiert und die genutzt werden sind. Aber eine Frage habe ich vorher noch: Wenn das jetzt nicht mehr funktioniert was da in den Specs beschrieben ist, wird denn dran gearbeitet das… Also einer aktuelleren Fassung, die diese Probleme lösen? Oder muss ich mir da selber was dranbauen? Oder muss ich jetzt einfach einen Moment damit leben, dass ich mich vielleicht nicht immer richtig schnell genug abmelden kann?

Stefan: Tatsächlich ist es so, dass ich nicht mitbekommen habe bisher, dass für, vor allem Dingen die Browserartigen Mechanismen, da… nach Alternativen gesucht wird, schon, aber dass schon welche gefunden worden wären. Es gibt Gespräche zwischen der OpenID Foundation und Browserherstellern, allen voran Apple, weil die einer der ersten Hersteller waren, die auf third party Inhalte besonders aggressiv reagiert haben, würde ich mal sagen. Aber da ist wahrscheinlich nicht wahnsinnig viel zu machen. Also da muss man glaube ich nochmal sehen, ob es da Lösungen geben wird oder ob man eben tatsächlich auf Server zu Server Mechanismen zurückgreifen muss und am Ende Back-End Channel das einzige ist, das übrigbleibt. So zu warten, ob der OpenID Connect Provider einen irgendwann über das Back-End mitteilt, dass irgendeine Session nicht mehr gültig ist.

Christoph: Ich finde wichtig, dass man das weiß, wenn man sich auf OpenID Connect einlässt, dass es da noch so gewisse Stellen gibt, die sozusagen undefiniert sind momentan und es noch nicht klar ist, wie es da weiter geht. Kommen wir dann mal auf die low-level Bausteine. Simon, du hattest gerade von JWT gerade geredet, das ist ja das JSON Web Token (JWT). Aber da gibt es noch so ein paar andere Abkürzungen: JWK, JWS und noch ein paar mehr, die da eine Rolle spielen. Willst du mal kurz erklären, was sich dahinter verbirgt? Und warum man die in OpenID Connect braucht?

Simon: Also JWT selbst ist ein JSON Format mit bestimmten Keys, die definiert sind. Es gibt mandatory claims, zum Beispiel, wann läuft dieses Token ab oder ähnliches, die sind immer vorhanden und OpenID Connect erweitert das eben um weitere Claims. Und neben dem JWT Token, was wahrscheinlich die häufigsten können, ist halt eben ein Teil von der JavaScript Object Signing and Encryption Spec Sammlung oder Gruppe, ich weiß gar nicht wie sich das genau aufteilt und hier habe ich einfach die Möglichkeit solche Benutzerclaims irgendwie zu übertragen. Und jetzt ist die Frage: Was brauche ich denn für Elemente für sowas? Naja, wir wollen wahrscheinlich diese Information irgendwie signieren, dass jemand auch überprüfen kann, ob die bei der Übertragung nicht verändert wurden. Unter Umständen ist das gar nicht für den Client interessant was da drinsteckt. Also wenn wir diese Inhalte irgendwie verschlüsseln. Und immer dann, wenn wir Dinge verschlüsseln, brauchen wir irgendwie eine Art Key Management und wir müssen uns irgendwie auf einen Algorithmus einigen. Und vielleicht haben wir noch ein paar andere abgefahrene Dinge, die wir übers Web übermitteln wollen, zum Beispiel so einen Fingerabdruck oder ähnliches. Und das alles sind quasi einzelne Specs, da gibt es dann halt eben einmal JSON Web Signature, JSON Web Encryption, JSON Web Key, JSON Web Algorithms, das JSON Web Token und eben JSON Web Key Thumbprint. Ich glaube das sind im Großen und Ganzen so die Kernteile davon. Die sind nicht Teil von OpenID Connect oder von OAuth, sondern die sind halt eben Teil von dieser JavaScript Object Signing and Encryption Spec und werden da halt eben benutzt. Wahrscheinlich wird man damit direkt höchstens auf so einer JWT Ebene irgendwie in Berührung kommen und das ergibt sich dann eben über die OpenID Connect Spec.

Stefan: Ja. Also im Wesentlichen haben wir da standardisierte Mechanismen, wie man JSON verschlüsseln, wie man JSON signieren kann und in der Regel sind die ID Token, die wir bei real existierenden OpenID Connect Providern sehen signierte JWTs. Dass ich, wenn ich das JWT in die Hand bekomme, die Signatur prüfen kann. Dazu muss ich möglicherweise bei…, muss ich den Schlüssel kennen mit dem signiert wurde. Also im Fall von symmetrischer Kryptographie muss ich genau den Schlüssel kennen, mit dem die Signatur gemacht wurden ist. Bei asymmetrischer Kryptographie ist es mit dem privaten Schlüssel des OpenID Connect Provider signiert wurden und ich brauche dann also Zugriff zum öffentlichen Schlüssel. Und da kommen dann die JWKs, oder wie auch immer die dann ausgesprochen werden, ins Spiel. Also der Key Store, im Wesentlichen ein standardisiertes JSON Format, wie ich öffentliche Schlüssel für bestimmte asymmetrische Algorithmen, RSA und elliptische Kurven, zur Verfügung stellen kann. Und dann muss ich nicht einmal das Schlüsselmaterial auch verteilen, sondern in dem Discovery Dokument steht auch der URI drinnen auf dem ich die jetzt gerade gültigen Schlüssel des OpenID Connect Providers, die öffentlichen Schlüssel, abholen kann. Sodass dann auch der OpenID Connect Provider in der Lage ist Schlüssel zu rotieren, ohne dass ich im Client die Konfiguration ändern muss, wenn der Client nur regelmäßig genug dieses Key Set, ist es dann glaube ich, abholen kann.

Simon: Wenn man es total überspitzt formulieren wollen würde, könnte man einfach behaupten: Das sind SAML Assertions, die sind halt jetzt nicht mehr XML, die sind jetzt JSON.

Stefan: Tatsächlich macht JSON an der Stelle ein paar Dinge einfacher als XML Security, weil es für JSON weniger Optionen gibt, wie die gleichen Informationen realisiert werden könnten. Und dann definiert man, dass die Schlüssel alphabetisch sortiert werden bevor signiert wird, dass man den whitespace wegstript und solche Dinge. Und legt dann einmal fest, also die ganzen Profildinge, die bei XML Security mit reingespielt haben, dass man sich überhaupt erstmal auf den Normalisierungsmechanismus einigen muss, die hat man sich hier im JSON Fall zum Glück gespart.

Simon: Und XML im JavaScript Anwendungen, die ja leider Gottes zum modernen Internet dazugehören, zu parsen, ist halt auch nicht das, was man so als ersten Gedanken hat an der Stelle.

Christoph: Jetzt habt ihr ganz viel über das JWT und die anderen Specs, die da mit reinfließen, gesprochen, über so ein bisschen low level und Ziel. Aber was vielleicht untergegangen ist, was wir vielleicht nochmal wiederholen sollten, ist: Wo finden die denn in OpenID Connect Anwendungen? Also wo habe ich den JWT in der Hand?

Stefan: Das ID Token ist ein JWT. Das ist eigentlich so der einzige Punkt, an dem man definitiv mit einem JWT zu tun haben wird, an der Stelle. Die OpenID Connect Spezifikation sagt nicht, also das JWT könnte verschlüsselt sein, das könnte signiert sein. Das ist aber in beiden Fällen nicht festgelegt, also es wäre auch denkbar, dass ein JWT weder das eine noch das andere ist. Und…

Simon: Ja, die OAuth 2.0 Token Introspection kann man da noch erwähnen. Da ist halt letztendlich definiert…, also man bekommt nicht ein JWT als irgendwie File zurück oder ähnliches, aber das Datenformat ist letztendlich ein JWT, was da über die Schnittstelle kommt.

Stefan: Genau. Etwas was an der Stelle vielleicht, wir auch nochmal erwähnen sollten, ist: Es gibt zum Umgang mit solchen JWTs Bibliotheken, die man nutzen kann. Man kann natürlich auch versuchen die Dinge selber zu parsen, dass ist eigentlich gar nicht so wahnsinnig kompliziert. Das ist nur base64 kodiertes JSON im Wesentlichen, aber es ist relativ einfach Dinge falsch zu machen in dem Zusammenhang. Es gab gerade in dem Kontext von den Signaturen Schwachstellen in sehr vielen verbreiteten Bibliotheken, dass man ihnen einfach unterjubeln konnte, dass ein JWT angeblich von einem Server signiert wäre, indem man eine Schwäch ausgenutzt hat, dass die Bibliotheken nicht wirklich genau auf den Algorithmus geguckt haben, von dem der OpenID Connect Provider sagt, er würde ihn benutzen zum Signieren. Und dann hat der OpenID Connect Provider vielleicht ein asymmetrisches kryptographisches Verfahren benutzt und man hat der Relying Party ein JWT präsentiert und gesagt, das ist symmetrisch verschlüsselt und hat den öffentlichen Schlüssel des OpenID Connect Providers, den man ja runterladen kann, als Schlüssel verwendet. Und damit eine Verwirrung in der Bibliothek gestiftet, die dann Signaturen geglaubt hat, die einfach in der Form nicht gültig waren. Da sind praktisch alle Bibliotheken ursprünglich mal anfällig gewesen, das ist vor 2–3 Jahren glaube ich gefixt wurden in den meisten Bibliotheken.

Simon: Das ist ja schon die advanced Version. Das Problem so an der Stelle, ich kann halt eben auch sagen: Das ist gar kein signiertes… Also der Signatur der Algorithmus, der benutzt wurde, den setzte ich halt eben auf none und dann ist das natürlich ein valides Token, was ich da bekomme. Und jede Bibliothek, die dieses Token erstmal parst, wird dann nicht unbedingt eine exception oder ähnliches werfen, weil das Token selbst ist noch valide. Das steht ja im Header drin, dass keine Signatur dahinter hängt. Und es liegt halt in der Verantwortung vom Benutzer, in der Implementierung darauf zu achten, dass ich hier auch wirklich ein signiertes Token bekomme und nicht irgend… Und natürlich den Schlüssel, den ich erwarte, dass der an der Stelle auch matched. Und die Bibliotheken am Anfang haben halt ganz oft auch diesen Unterschied gar nicht mehr sichtbar gemacht. Und wenn ich einfach nur sowas sage wie: Ich habe jetzt JWT Tokens, das sind alles JWT Tokens. Und dann musste ich am Anfang zumindest, als Benutzer selbst nochmal darauf achten, dass der richtige Signaturalgorithmus benutzt wurde. Inzwischen abstrahieren die Bibliotheken das aber normalerweise auch soweit, dass sie dann so ein signiertes JWT, heißt dann halt eben auch die Klasse einfach nicht mehr JWT, sondern dann ist die Klasse JWS und wenn ich da versuche irgendwie Input reinzuschieben, der nicht signiert ist, dann wird da auch eine exception geworfen oder ähnliches. Aber das kommt immer noch vor, dass die Leute einfach Signaturen von diesem JWT Token nicht prüfen und das ist einfach immer, wenn man damit zu tun hat, darauf achten bitte, dass man auch diese Signatur überprüft. Ich möchte nicht, dass ein Benutzer beliebige Rollen in so ein Token selbst reinschreiben kann und darüber vielleicht dann plötzlich Admin Rechte in der Applikation hat.

Christoph: Das Problem, was ja glaube ich insgesamt in dieser JWT Spezifikation steckt, ist, dass der Nutzer vorgibt, wie die Integritätsprüfung laufen soll. Also der Algorithmus ist ja vom Nutzer gegeben, also der das ausstellt und nicht von dem, der es überprüft. Also dann kann ich da halt ein none reinstecken oder symmetrisch und asymmetrisch vertauschen und ähnliches. Aber mal weg…

Simon: Also ganz so hart würde ich es nicht formulieren. Letztendlich ist JWT halt ein Datenformat auf JSON Basis und ich kann das irgendwie verwenden. Und natürlich möchte ich vielleicht eine Option haben sowas auch ohne Signatur zu benutzen und dann steht das halt eben da im Header drin. Drum kümmern muss ich mich natürlich in jedem Fall selbst, selbst wenn es den Header nicht gäbe, müsste ich natürlich irgendwie die Prüfung von der Signatur auch wirklich selbst implementieren. Das nimmt mir ja niemand ab.

Christoph: Das stimmt. Aber nochmal weg von den Sicherheitsaspekten. Was ich gerne betonen würde ist, zu der Anwendung und im Gegensatz zu OAuth 2.0, ist halt das ID Token immer ein JWT und das heißt ich weiß immer was ich…, sozusagen wie ich das parsen kann. Da das Access Token ja erstmal völlig opaque für mich ist, da weiß ich das erstmal nicht in OAuth. Da kann irgendwas drinstehen, das ist ein String, der für mich keine Bedeutung hat. Und das macht natürlich dann leichter mit so einem ID Token umzugehen oder auf so einem System zu implementieren, wenn das spezifiziert ist. So, dann haben wir jetzt wahrscheinlich alles zusammen, um so ein SSO System zu bauen mit OpenID Connect. Das ist aber wahrscheinlich nicht das Einzige. SAML habe ich öfter schon gehört, aber gibt es da noch Alternativen dazu? Oder sollte ich heutzutage immer auf OpenID Connect setzen? Und wenn nicht, warum sollte ich nicht daraufsetzen?

Simon: Na, ich fange mal ganz dreist warum da nicht drauf setzen sollte an. Und dann können wir es ja ergänzen. Aber die Frage ist natürlich: Will ich Single Sign On? Also ist das eine Notwendigkeit, die ich in meinen Systemen implementieren möchte? Wenn ja, dann macht das sicherlich Sinn. Also es gibt Alternativen, wie SAML, es gibt die ganzen Microsoft Protokolle, wo ich mir nie sicher bin, ob es jetzt Kerberos ist oder wie die aktuell die Windows Authentification Services heißen. Aber letztendlich ist natürlich die Frage oder beziehungsweise das, was wir häufig auch in Projekten vorfinden, wir haben 2–3 kleinere Applikationen und dann baut man halt eben im Projekt nebenbei noch Single Sign On mit einem Identity Provider auf. Und mir muss eigentlich klar sein, dass ist nicht Infrastruktur, die sich von selbst betreibt, die ich nicht warten muss. Es ist kritische Infrastruktur, die irgendwann mal ausfällt und ganz häufig findet man eigentlich sowas, so eine Umgebung vor, in der halt eben vielleicht drei Applikationen wissen wollen, ob das der Benutzer ist und sich halt eben einen Log In teilen. Und in so Fällen tut es vielleicht manchmal auch einfach ein signierter Cookie, den ich entsprechend nochmal vielleicht verschlüssle, wenn ich nicht will, dass da irgendwelche Rollen oder ähnliches ausgewiesen werden und es ist gar nicht notwendig an der Stelle Single Sign On umzusetzen. Ich muss mir sicher sein, ich möchte Single Sign On mit all den Vorteilen, die das eben bietet, aber das bedeutet nicht, dass der Benutzer automatisch angemeldet ist. Also wenn ich sowas als einziges Feature habe, dann bin ich immer noch nicht bei Single Sign On an der Stelle.

Stefan: Das was du beschrieben hast über das signierte Cookie, ist ja in einen gewissen Kontext möglicherweise auch ein Single Sign On. Eben ein sehr beschränktes auf die drei Services, die du dort gesehen hast. Und den technischen Kontext voraussetzt, dass alle drei das gleiche Cookie sehen können. Also damit, wenn wir auf Browser schauen, in der gleichen Top-Level-Domain…, nicht Top-Level-Domain, sondern Second-Level-Domain mindestens mal legen müssen. OpenID Connect und SAML, SAML ist einfach das ältere Protokoll, das ein paar zusätzliche Use Cases noch über OpenID Connect hinaus abdecken kann, aber im Wesentlichen ähneln sich OpenID Connect und SAML doch sehr stark, nur dass das eine auf XML und das andere auf JSON aufsetzt. Und da gibt es dann noch so ein paar weitere Erweiterungen. Die beiden Protokolle sind sicherlich die, die man am häufigsten antrifft, wenn man Domainübergreifend SSO machen möchte und da würde ich auch nicht dazu raten etwas Eigenes zu erfinden, wenn man über mehrere Domaingrenzen hinweg irgendwas tun möchte. Da muss man manchmal eben gucken, was unterstützen denn die Dinge, mit denen ich vielleicht integrieren möchte, von Haus aus? Was durchaus schonmal vorkommt ist, dass man für eine bestimmten Kontext SSO einführen möchte und integrieren möchte mit anderen Anwendungen, die schon existieren. Und die können dann vielleicht nur SAML oder die können vielleicht nur OpenID Connect, so dass dadurch dann ein Stück weit die Auswahl schon eingeschränkt ist, was man tun möchte. Und dann gibt es Produkte, die sowohl OpenID Connect Provider als auch SAML Identity Provider gleichzeitig sein können. Die sich dann für sowas möglicherweise anbieten, wenn man mit mehreren Third-Party-Applikationen zusammenspielen möchte.

Christoph: Du erwähntest gerade, dass man, wenn man so ein SSO Ding macht, dass man vielleicht nicht selber baut. Also so eine einfache Lösung, wie der Simon das erwähnt hat, die vielleicht auch eine ganze Reihe Use Cases abdeckt. Ich hatte jetzt mal so geguckt, ohne jetzt groß irgendwelche Produkte oder Hersteller zu nennen, was es da denn so gibt. Und da ist mir eins aufgefallen: Überall wo ich SSO einkaufen will, ist die Sprache von identity Management. Ist denn identity Management dasselbe wie SSO? Oder wie hängen die beiden Begriffe da zusammen?

Simon: Naja, ohne mich jetzt hundert Prozent darauf festlegen zu wollen, aber ich würde schon Single Sign On als Stück weit Teil von einem identity Management sehen. Hier sind wir halt irgendwie ein Stück weit eh im Enterprise Umfeld, wo wir eine ganze Reihe an buzzwords haben, die auch breit bedient werden. Aber natürlich habe ich ein Interesse daran die Identität des Benutzers zentral zu managen, wenn ich halt eben große verteilte Systeme baue. Und das geht ja darüber hinaus, dass der Benutzer sich nur anmelden kann, sondern ich will ja auch eine entsprechende, zum Beispiel Passwort-Reset-Funktionalität da irgendwie abbilden. Ich will komplexere Workflows im Hintergrund haben, wo ich entscheiden kann: Was bekommt der Benutzer denn für eine Rolle? Kann er das vielleicht in so einem Self-Service Portal beantragen. Und alles was wir da irgendwie aus dem Umfeld so kennen hängt da noch ein Stück weit mit dran. Deswegen muss man sagen, wenn es da um Produkte oder ähnliches geht, also ich könnte da gar nicht pauschal so das eine Ding empfehlen oder das eine Produkt, die haben alle irgendwie Vor- und Nachteile und man muss sich darüber im klaren sein, dass man in so einem Fall sehr schnell halt eben an das größere Thema Identity Management kommt. Und da ist halt auch wieder die Frage, man muss so ein bisschen auf Scope achten, gehört das eigentlich gerade in das Projekt oder ist das halt eben grundlegende Infrastruktur, die man da aufbaut. Und da fallen dann wahrscheinlich noch viel, viel mehr Kriterien rein als halt eben ein Identity Provider, der nur SAML oder nur OpenID Connect spricht.

Stefan: Würde ich ähnlich einsortieren. Ich würde SSO als eine Facette von Identity Management betrachten, wo eben noch zusätzliche Dinge dazugehören. Was man auch häufig dann noch hat sind Migrationsszenarien, wenn man eben so ein neues Identity Management System in eine gewachsene Infrastruktur einführt wo möglicherweise schon Datentöpfe mit Benutzerdaten, die in irgendeiner Art und Weise konsolidiert werden sollen, existieren, die dann zusammengeführt werden müssen, Duplikate gefunden. All die Prozesse, die da noch mit dranhängen. Dort unterstützen dann möglicherweise größere Identity Management Produkte diese oder jene Funktionalität, die weit über das hinausgehen, was man für SSO benötigen würde.

Christoph: Gut, also man kann da nicht so einfach gleichsetzen, sondern Identity Management umfasst auch eine ganze Reihe mehr Dinge als SSO und SSO ist vielleicht ein Teil von Identity Management. Gut, ich glaube dann haben wir es für heute, wenn ihr nicht noch irgendwas sagt, was: Das haben wir jetzt vergessen, müssen wir noch unbedingt ergänzen! Das scheint nicht der Fall zu sein. Dann bedanke ich mich bei dir Stefan! Ich bedanke mich bei dir Simon! Ich bedanke mich bei unseren Hörer:innen! Und wenn ihr Lob, Kritik, Verbesserungen, Themenvorschläge habt, dann schreibt uns doch an [email protected]. Und wenn es euch gefallen hat, gibt uns eine gute Bewertung. Und damit sage ich: Bis zum nächsten Mal! Ciao!

TAGS

Senior Consultant

Christoph Iserlohn ist Senior Consultant bei INNOQ. Er hat langjährige Erfahrung mit der Entwicklung und Architektur von verteilten Systemen. Sein Hauptaugenmerk liegt dabei auf den Themen Skalierbarkeit, Verfügbarkeit und Sicherheit.

Alumnus

Simon Kölsch arbeitete bis Juli 2023 als Information Security Officer bei INNOQ.

Senior Consultant

Stefan Bodewig arbeitet als Senior Consultant bei INNOQ und entwickelt seit vielen Jahren Software auf der JVM und der .NET Plattform. Er ist Mitglied der Apache Software Foundation und Committer bei diversen Open Source Projekten.