Konfiguration von Access Tokens in Keycloak

Konfiguration von Access Tokens in Keycloak

In den ersten Beiträgen haben wir uns angeschaut, wie skalierbares RBAC aufgebaut und in Keycloak umgesetzt werden kann. Dabei haben wir die Keycloak Clients genutzt, um die anwendungsspezifischen Rollen in einem eigenen Namespace zu definieren.

In diesem Beitrag schauen wir uns an, wie wir einen Keycloak Client konfigurieren und nutzen, um Access Tokens für den Zugriff auf einen Resource Server zu generieren. Die folgenden Komponenten und Konzepte schauen wir uns dafür an:

  • OAuth 2.0 Clients
  • Keycloak Clients
  • Keycloak Protocol Mapper
  • Keycloak Client Scopes

Das schwierigste bei der Arbeit mit Keycloak ist in meinen Augen, dass Begriffe wie Clients innerhalb von Keycloak anders definiert sind als in gängigen Spezifikationen wie z.B. RFC 6749: The OAuth 2.0 Authorization Framework. Deshalb beginne ich mit einem kurzen Abschnitt, in dem ich die Begriffe aus der OAuth 2.0 Spezifikation definiere - wie im letzten Beitrag. Auf diese Weise haben wir ein einheitliches Verständnis der relevanten Begriffe. Hinweis: Wenn ihr die letzten beiden Beiträge bereits gelesen habt, könnt ihr den folgenden Abschnitt überspringen.

Begriffsdefinitionen

Der Resource Server, der Authorization Server und der Client sind im Kontext der OAuth 2.0 Spezifikation lediglich als Rollen zu verstehen. Es werden also Verantwortlichkeiten und keine konkreten Entitäten definiert.

Resource Server: Server, der die geschützten Ressourcen bereitstellt. Nutzt Access Tokens, um die Requests zu den geschützten Ressourcen zu verarbeiten (Definition laut RFC 6749).

Authorization Server: Server, der die Access Tokens ausstellt, nachdem sich der Nutzer erfolgreich angemeldet hat (Definition laut RFC 6749). In diesem Beitrag besitzt Keycloak die Rolle des Authorization Servers.

(OAuth 2.0) Client: Eine Anwendung, die geschützte Ressourcen im Auftrag des Nutzers anfragt (Definition laut RFC 6749). Wichtig: wenn wir in Keycloak Clients anlegen, handelt es sich nicht in jedem Fall um einen Client mit der Rolle eines OAuth 2.0 Clients. In skalierbares RBAC mit Keycloak haben wir einen Keycloak Client bspw. genutzt, um einen Namespace für anwendungsspezifische Rollen zu erstellen. Dieser Client repräsentiert den Resource Server und nicht die Anwendung, die geschützte Ressourcen anfragt.

Keycloak Clients vs. OAuth 2.0 Clients

Im RFC 6749 wird der Client als Rolle definiert, dessen Inhaber Access Tokens anfordert. In Keycloak ist ein Client jedoch eine konkret konfigurierte Entität. Um Keycloak effektiv zu nutzen, muss verstanden werden, an welchen Stellen der Keycloak Client über den OAuth 2.0 Standard hinausgeht.

Der Keycloak Client als Konfigurationsobjekt: In Keycloak wird ein Client als Konfigurationsobjekt verwendet, das die Identität einer Anwendung gegenüber Keycloak repräsentiert. Hier werden alle sicherheitsrelevanten Einstellungen wie erlaubte Redirect-URIs, Web-Origins für CORS sowie der verwendete Authorization Flow konfiguriert.

Der Keycloak Client als Namespace für Basisrechte, Basisrollen und lokale Berechtigungsprofile: In Keycloak können Client roles innerhalb eines Clients definiert werden. Basisrechte, Basisrollen und lokale Berechtigungsprofile lassen sich so für einen spezifischen Resource Server definieren und sauber kapseln. Wenn eine Client role andere Client roles enthält, spricht man von einer Composite client role. Diese Rollen werden für die Basisrollen und lokalen Berechtigungsprofile verwendet. Was genau Basisrechte, Basisrollen und lokale Berechtigungsprofile sind, haben wir in skalierbares RBAC auf konzeptioneller Ebene behandelt.

Integrierte Service Accounts: Laut RFC 6749 fragt eine Anwendung, die die Rolle des OAuth 2.0 Clients besitzt, Access Tokens im Auftrag eines Nutzers an. Keycloak Clients verfügen aber auch über integrierte Service Accounts. Ist diese Funktion aktiviert, kann eine Anwendung eigenständig, ohne externen Nutzer, Access Tokens anfordern.

Keycloak Protocol Mapper

Ein Protocol Mapper ist die Komponente, die für die Konstruktion der Tokens verantwortlich ist. Der Mapper definiert, welche Informationen tatsächlich im Token landen. Die Informationen werden innerhalb des Tokens durch sogenannte Claims repräsentiert.

Ein Protocol Mapper arbeitet nicht isoliert. Er stellt sicher, dass nur die Daten im Token landen, die der Benutzer tatsächlich besitzt und für die der anfragende Keycloak Client über seine zugewiesenen Scopes berechtigt ist.

Keycloak Client Scopes

Client Scopes in Keycloak sind Container, die mehrere Protocol Mapper und/oder Role Mappings bündeln können. Während Protocol Mapper definieren, wie bestimmte Informationen in das Token geschrieben werden, legen die Client Scopes fest, wann und für wen diese Mapper ausgeführt werden.

Benötigen verschiedene Clients die gleichen Protocol Mapper, werden diese Protocol Mapper in einem Client Scope gebündelt. Anschließend wird dieser Client Scope den relevanten Clients zugewiesen. Die Alternative wäre, identische Protocol Mapper in den entsprechenden Clients zu erstellen. Das erhöht den Konfigurationsaufwand deutlich.

Client Scopes können als optional oder default konfiguriert werden. Bei einem Scope, der als default konfiguriert ist, werden die Protocol Mapper für alle Tokens ausgeführt, die von Keycloak für den Client ausgestellt werden. Die innerhalb des Client Scopes gebündelten Protocol Mapper schreiben die Informationen also in alle Tokens. Ist ein Client Scope als optional konfiguriert, schreiben die entsprechenden Protocol Mapper die Informationen nur dann in den Token, wenn der zugehörige Token Request den optionalen Client Scope explizit anfragt.

Was haben Keycloak Client Scopes mit OAuth 2.0 Scopes zu tun?

Keycloak Client Scopes sind das Bindeglied zwischen der OAuth 2.0 Spezifikation und der tatsächlichen Token-Generierung. Sowohl die OAuth 2.0 Spezifikation als auch der Keycloak Server Administration Guide definieren das Scope-Konzept als zentrales Instrument zur Steuerung von Berechtigungen und Token-Inhalten.

Laut der OAuth 2.0 Spezifikation nutzt der Client den scope Request-Parameter am Token-Endpoint, um den Umfang der Zugriffsanforderung ("scope of the access request") als eine Liste Leerzeichen-separierter Strings zu spezifizieren (bspw. scope=profile oid:sid:resource:read). Fehlt dieser Parameter, verlangt die Spezifikation zwingend, dass der Request entweder mit einem Standardwert verarbeitet, oder mit der Fehlermeldung invalid scope abgelehnt wird.

Keycloak implementiert diese Spezifikation. Die in Keycloak konfigurierbaren "Default Client Scopes" repräsentieren die Standardwerte, wenn der Request keinen scope Parameter enthält. "Optional Client Scopes" hingegen, werden genau dann ausgewertet, wenn sie explizit vom scope Parameter definiert werden (bspw. scope=profile oid:sid:resource:read).

Der wesentliche Unterschied zwischen OAuth 2.0 Scopes und Keycloak Client Scopes besteht darin, was die Scope-Strings für den Server bedeuten. Laut Spezifikation repräsentieren diese Strings für den Authorization Server lediglich abstrakte Zugriffsbereiche, für die eine Zugriffserlaubnis angefragt werden kann. In Keycloak hingegen, ist ein solcher String nicht nur ein abstrakter Zugriffsbereich, sondern verweist direkt auf ein Konfigurationsobjekt - den konkreten Client Scope. Wie bereits erwähnt, bündelt dieser Client Scope protocol mappers und role scope mappings. Keycloak nutzt den im Request übermittelten String (bspw. scope=profile oid:sid:resource:read) somit als Auslöser: entspricht der String einem vorhandenen Client Scope, führt Keycloak die darin konfigurierten Mapper aus, um das Token mit spezifischen Claims und Rollen zu füllen.

Inhalte der Access Tokens mit Keycloak steuern

(Hinweis: Für die folgenden Schritte nutze ich Keycloak in der Version 26+)

Im Beitrag über skalierbares RBAC mit Keycloak haben wir gemeinsame eine Rollen- und Rechte-Hierarchie aufgebaut. Diese Hierarchie ist die Grundlage für die folgenden Konfigurationen. An dieser Stelle eine kurze Zusammenfassung:

Zuerst haben wir die Basisrechte definiert, die unser Resource Server benötigt und verarbeiten kann. Diese Basisrechte habe ich im Vergleich zum letzten Beitrag erweitert. Die Namenskonventionen haben wir in skalierbares RBAC auf konzeptioneller Ebene definiert. Der Keycloak Client, den wir nutzen, heißt backend-anwendung1-rs. Das -rs steht für Resource Server und bedeutet, dass dieser Keycloak Client ausschließlich dafür genutzt wird, die Basisrechte, Basisrollen und lokalen Berechtigungsprofile zu definieren. Die folgende Abbildung zeigt alle verfügbaren Basisrechte.

Diese Basisrechte sind in vier anwendungsspezifischen Basisrollen gebündelt:

  • oid:ba1:role_1 - book read, enthält:
    • oid:ba1:book:read
  • oid:ba1:role_2 - book write, enthält:
    • oid:ba1:book:write:create
    • oid:ba1:book:write:update
    • oid:ba1:book:write:delete
  • oid:ba1:role_3 - member read, enthält:
    • oid:ba1:member:read
  • oid:ba1:role_4 - member write, enthält:
    • oid:ba1:member:write:create
    • oid:ba1:member:write:update
    • oid:ba1:member:write:delete

Da sich die Inhalte der Rollen ändern können, befindet sich die menschenlesbare Beschreibung in der Beschreibung der Rolle und nicht in der ID.

Die vier Basisrollen sind wiederum in zwei verschiedenen lokalen Berechtigungsprofilen gebündelt. Es existiert ein Profil für einen Bibliothekar und ein Profil für einen Besucher der Bibliothek. Der Bibliothekar hat sowohl Lese- als auch Schreibrechte für Bücher und Mitglieder. Mitglieder haben ausschließlich Leserechte für Bücher und Mitglieder. In einer echten Anwendung darf ein Besucher vermutlich nur sein eigenes Profil sehen, der Einfachheit halber belassen wir es in diesem Beispiel bei einem globalen Leserecht für alle Mitglieder.

  • oid:ba1:comp_role_1 - Bibliothekar, enthält:
    • oid:ba1:role_1 - book read
    • oid:ba1:role_2 - book write
    • oid:ba1:role_3 - member read
    • oid:ba1:role_4 - member write
  • oid:ba1:comp_role_2 - Besucher, enthält:
    • oid:ba1:role_1 - book read
    • oid:ba1:role_3 - member read

Entsprechend dieser Konfiguration gibt es ebenfalls zwei globale Berechtigungsprofile, die einen Bibliothekar und einen Besucher repräsentieren. Globale Berechtigungsprofile werden in Keycloak durch Gruppen dargestellt. Jede Gruppe enthält ausschließlich die zugehörigen lokalen Berechtigungsprofile. Die folgenden Abbildungen zeigen die beiden globalen Berechtigungsprofile oid:comp_role_1 (Bibliothekar) und oid:comp_role_2 (Besucher):

Nehmen wir den Haken bei Hide inherited roles raus, können wir alle Rollen sehen, die vererbt und somit den Mitgliedern dieser Gruppe zugewiesen werden. Die folgende Abbildung zeigt das am Beispiel von oid:comp_role_1 (Bibliothekar):

Darüber hinaus habe ich zwei Testnutzer erstellt. John Doe ist Mitglied der Gruppe oid:comp_role_1 und somit ein Bibliothekar. Jane Doe ist Mitglied der Gruppe oid:comp_role_2 und somit ein Besucher der Bibliothek.

Diese Konfiguration entspricht einem skalierbaren RBAC System. Die Rollen- und Rechteverwaltung ist von der Nutzerverwaltung getrennt. Nutzer könnten so beispielsweise auch durch LDAP angebunden werden.

1) Scopes konfigurieren

Damit wir steuern können, welche Basisrechte am Ende im generierten Access Token enthalten sind, müssen wir zunächst Scopes konfigurieren. OAuth 2.0 Scopes werden genutzt, um zu steuern welche Berechtigungen ein Client überhaupt anfordern darf. Dazu ein kurzes Beispiel:

John Doe ist Bibliothekar und hat sowohl Lese- als auch Schreibrechte für Mitglieder und Bücher der Bibliothek. Wenn John über die Admin-Webanwendung in der Bibliothek auf die Systeme zugreift, kann er diese Lese- und Schreibrechte vollumfänglich nutzen. Das ist möglich, weil der zugehörige Keycloak Client so konfiguriert ist, dass diese Webanwendung alle Scopes anfordern darf.

Seit neuestem hat die Bibliothek auch eine mobile App, die John außerhalb seines Arbeitsplatzes nutzen kann. Diese App ist jedoch weniger vertrauenswürdig als die Admin-Webanwendung. Der dazugehörige Keycloak Client ist so konfiguriert, dass die App nur die Leserechte für Mitglieder und für Bücher anfordern darf. Die Berechtigungen von John sind unverändert. Trotzdem darf er innerhalb der mobilen App nur lesend auf Mitglieder und Bücher zugreifen. Genau diesen Sachverhalt können wir über Scopes abbilden.

Für unseren Resource Server werden wir die folgenden vier Scopes definieren:

  • oid:ba1:book:read
  • oid:ba1:book:write
  • oid:ba1:member:read
  • oid:ba1:member:write

Diesen Scopes weisen wir jeweils die relevanten Basisrechte (Client Roles) der Anwendung backend-anwendung1-rs zu. Anschließend erstellen wir einen Protocol Mapper pro Scope. Dieser Mapper ist dafür zuständig, die zugeordneten Basisrechte in den Access Token zu schreiben. Die folgenden Schritte sind dementsprechend notwendig:

  1. Keycloak Client Scopes erstellen
  2. Jedem Scope die Basisrechte zuordnen, die dieser Scope in den Token bringen darf
  3. Pro Scope einen Protocol Mapper konfigurieren, der diese Basisrechte am Ende auch in das Access Token schreibt

Wichtig: nicht alle Basisrechte, die dem Scope zugewiesen werden, müssen am Ende zwangsläufig im Access Token stehen. Wie ich versucht habe im Beispiel zu verdeutlichen, steht nur die Schnittmenge der Basisrechte im Access Token, die der Client anfordern darf (und tatsächlich auch anfordert) und die dem Nutzer über seine Gruppenzugehörigkeit zugeordnet wurden.

Um einen Scope zu erstellen, navigieren wir in der Seitenleiste zu Client scopes und klicken auf den Button Create client scope.

In der Maske, die sich anschließend öffnet, konfigurieren wird die Felder Name, Description, Type und Include in token scope. Den Type setzen wir auf Optional, damit der Scope nicht standardmäßig in jedes Access Token geschrieben wird, sondern explizit angefordert werden muss. Wir wollen die Tokens in jedem Fall so ausstellen, dass sie ausschließlich die notwendigen Basisrechte enthalten und nicht mehr.

Hinweis: Wenn wir den Type eines Client scopes an dieser Stelle auf Optional oder Default setzen, wird dieser Scope standardmäßig jedem neuen Client als Optional oder Default hinzugefügt - je nachdem was wir an dieser Stelle auswählen. Dieses Verhalten wird ziemlich lästig, sobald wir mehrere Anwendungen mit Keycloak absichern wollen. Neu erstellte Clients enthalten dann nämlich bereits alle möglichen Client Scopes die wir jemals erstellt und an dieser Stelle als Optional oder Default markiert haben. Dadurch hat der Client auch viel zu viele Berechtigungen. Unser Standardvorgehen sollte es also sein, den Type in dieser Maske auf None zu belassen.

Nach einem Klick auf Save öffnet sich die Übersichtsseite des neu erstellten Scopes. Hier navigieren wir nun über den Reiter Scope auf die Maske, die es uns ermöglicht, die Rollen zu definieren, die dieser Scope in das Access Token bringen darf. Über den Button Assign role -> Client roles weisen wir dem Scope nun die Rolle bzw. das Basisrecht oid:ba1:book:read zu.

Nachdem wir die Rollen definiert haben, die der Scope in das Access Token bringen darf, müssen wir noch konfigurieren, wie diese Rollen in das Access Token geschrieben werden. Dafür müssen wir einen Protocol Mapper für den Scope konfigurieren. Um einen Mapper zu erstellen, navigieren wir über den Reiter Mappers auf die entsprechende Unterseite und fügen über den Button Configure a new mapper einen neuen Mapper hinzu. Es öffnet sich eine Liste mit mappings. Aus dieser Liste wählen wir das Mapping User Client Role aus. Wenn es nicht direkt angezeigt wird, müsst ihr ein Stück nach unten scrollen.

Anschließend konfigurieren wir die Felder Name, Client ID und Token Claim Name. Den Namen des Mappers versuche ich immer möglichst deskriptiv zu halten. Die linke Seite des Namens besteht aus dem Claim, der gefüllt werden soll und die rechte Seite enthält eine kurze Beschreibung von dem, was in den Claim geschrieben werden soll.

Die Client ID definiert den Client, aus dem die Rollen in den Claim geschrieben werden sollen. In unserem Beispiel ist das backend-anwendung1-rs, weil wir dort die Rollen bzw. Basisrechte definiert haben, die nun in das Access Token geschrieben werden sollen.

Als Token Claim Name geben wir eine Zeichenkette an, die durch Keycloak automatisiert gesetzt wird. In unserem Fall wird ${client_id} durch backend-anwendung1-rs ersetzt.

Damit haben wir den ersten unserer vier Scopes konfiguriert. Der Ablauf für die verbleibenden Scopes ist identisch. Es unterscheiden sich lediglich die Bezeichner der Scopes, die Namen der Mapper und die Rollen, die ein Scope in das Access Token bringen darf.

Der Scope oid:b1:book:write wird folgendermaßen konfiguriert:

  • Scope Name: oid:b1:book:write
  • Description: Provides write access to the backend-anwendung1 API.
  • Assigned Client Roles:
    • oid:ba1:book:write:create
    • oid:ba1:book:write:update
    • oid:ba1:book:write:delete
  • Mapper Name: resource_access.backend-anwendung1-rs.roles <- book write

Der Scope oid:b1:member:read wird folgendermaßen konfiguriert:

  • Scope Name: oid:b1:member:read
  • Description: Provides read access to the backend-anwendung1 API.
  • Assigned Client Roles:
    • oid:ba1:member:read
  • Mapper Name: resource_access.backend-anwendung1-rs.roles <- member read

Der Scope oid:b1:member:write wird folgendermaßen konfiguriert:

  • Scope Name: oid:b1:member:write
  • Description: Provides write access to the backend-anwendung1 API.
  • Assigned Client Roles:
    • oid:ba1:member:write:create
    • oid:ba1:member:write:update
    • oid:ba1:member:write:delete
  • Mapper Name: resource_access.backend-anwendung1-rs.roles <- member write

Am Ende sollten alle vier Scopes folgendermaßen in der Liste der Keycloak Client Scopes angezeigt werden:

Hinweis: Wenn ihr den Type wie o.a. auf None belassen habt, wird als Assigned type an dieser Stelle auch None statt Optional angezeigt.

2) Keycloak Client konfigurieren

Als nächstes müssen wir einen Keycloak Client konfigurieren, der Access Tokens ausstellen kann. Dieser Client ist also auch ein Client im Sinne der OAuth 2.0 Spezifikation.

Wir gehen an dieser Stelle nicht auf die Konfigurationsmöglichkeiten von Keycloak Clients ein. Hierfür wird es einen gesonderten Beitrag geben. Wir konfigurieren den Client dementsprechend pragmatisch und nicht nach Best Practices und gängigen Sicherheitsstandards. Der Keycloak Client wird ausschließlich genutzt, um zu demonstrieren, wie die Access Tokens am Ende aussehen und welche Einstellungen ein Client in Bezug auf diese Access Tokens vornehmen sollte.

Um einen neuen Client zu erstellen, navigieren wir in der linken Seitenleiste zu Clients. Dort erstellen wir über den Button Create client einen neuen Keycloak Client. Anschließend legen wir die Client ID, den Name und eine Description fest. Wir tun in diesem Beispiel so, als hätten wir ein Frontend für die Anwendung 1. Dieses Frontend greift dann mit den ausgestellten Access Tokens auf das Backend zu. Der Präfix -oauth bedeutet, dass dieser Keycloak Client keinen Resource Server repräsentiert, sondern einen Client im Sinne von OAuth 2.0, der Access Tokens ausstellt.

Auf der nächsten Seite aktivieren wir ausschließlich den Direct Access Grant. Dadurch können wir uns direkt mit Nutzername + Passwort anmelden. Das Vorgehen sollte außerhalb von diesem Beispiel nicht genutzt werden.

Die Felder Root URL und Home URL können ebenfalls leer bleiben. Anschließend landen wir auf einer Übersichtsseite.

Als nächstes müssen wir definieren, welche Scopes der Client anfordern darf. Hinweis: Habt ihr bereits beim Erstellen der Client Scopes als Type Optional ausgewählt, befinden sich die Scopes bereits in der Liste der Client Scopes für diesen Client und ihr müsst nichts weiter tun.

Habt ihr als Type None ausgewählt, müsst ihr die Client Scopes nun manuell hinzufügen. Hierfür navigieren wir über den Reiter Client scopes zu der entsprechenden Konfigurationsseite. Über den Button Add client scope können wir unsere erstellten Scopes hinzufügen. Dieser Client soll alle Scopes anfordern können. Deshalb wählen wir alle erstellten Scopes aus und fügen sie dem Client als optionale Scopes hinzu.

Bevor wir die nächsten Aspekte der Konfiguration ändern, schauen wir uns an, wie ein generiertes Access Token für den Nutzer John Doe aktuell aussehen würde. Hierfür navigieren wir über den Reiter Evaluate auf eine Seite, die uns beispielhaft darstellt, wie das Token aussehen wird. In dem Eingabefeld Scope parameter wählen wir nun alle vier optionalen Scopes aus. In dem zweiten Eingabefeld Users wählen wir John Doe. Zur Erinnerung: John Doe ist ein Nutzer, der unserer Gruppe oid:comp_role_1 zugeordnet ist. Diese Gruppe macht ihn in unserem Beispiel zu einem Bibliothekar. Wenn ihr an dieser Stelle noch nicht wisst, wofür Keycloak Groups benötigt werden und wie genau wir eine solche Gruppe konfigurieren, sei an dieser Stelle auf die ersten beiden Beiträge verwiesen:

Wenn alle relevanten Eingabefelder gefüllt sind, können wir über den Reiter Generated access token das daraus resultierende Access Token betrachten.

An dieser Stelle fällt auf, dass der Access Token viel zu viele Informationen bzw. Rollen enthält. Verantwortlich dafür ist die Option Full scope allowed. Diese ist standardmäßig für alle neuen Clients aktiviert.

Ist diese Option aktiviert, werden alle Rollen des authentifizierten Benutzers in das Access Token geschrieben - unabhängig davon, ob die anfragende Anwendung (der Client) diese Rollen/Berechtigungen überhaupt benötigt.

Die Deaktivierung dieser Option ist zwingend notwendig. Dadurch wird das Principle of Least Privilege umgesetzt. Das Access Token enthält anschließend nur noch die Rollen, die dem Client explizit über Scope Mappings (Scope + Protocol Mapper) zugewiesen wurden. Ein Client darf immer nur genau die Berechtigungen erhalten, die er für seine spezifische Aufgabe benötigt.

Um diese Option zu deaktivieren, navigieren wir auf der Seite Client scopes wieder zurück zu Setup. Hier klicken wir nun auf den blau hinterlegten dedicated Client Scope frontend-anwendung1-oauth-dedicated.

Auf der geöffneten Seite navigieren wir weiter über den Reiter Scope zu der nächsten Seite. Dort deaktivieren wir die Option Full scope allowed.

Schauen wir uns nun erneut auf der Seite Clients > frontend-anwendung1-oauth > Client scopes > Evaluate den generierten Access Token an, stellen wir fest, dass nur noch unsere gewünschten Basisrechte in dem Token vorhanden sind.

Führen wir nun die exakt gleiche Evaluation für den Nutzer Jane Doe aus, sehen wir, dass nur noch zwei Basisrechte im Token vorhanden sind. An dieser Stelle wird deutlich, dass nur die Schnittmenge der Basisrechte,

  • die die Scopes in den Token bringen dürfen und
  • die Basisrechte, die ein Nutzer über seine Gruppenzugehörigkeit besitzt,

in das Access Token gelangen. Da Jane Doe eine Besucherin der Bibliothek ist, besitzt sie nur Leserechte für Mitglieder und Bücher. Unser Client darf zwar auch die Scopes mit den Schreibrechten anfragen, da Jane diese Rechte jedoch nicht besitzt, stehen sie auch nicht im resultierenden Access Token.

Wenn wir den Client nun so konfigurieren würden, dass er nur noch die Scopes oid:ba1:book:read und oid:ba1:member:read anfordern dürfte, würde auch das Access Token für John Doe nur diese beiden Basisrechte enthalten, obwohl John selbst weitreichendere Berechtigungen besitzt. Simulieren können wir das, indem wir als Scope parameter nur diese beiden Scopes anfordern.

Wenn ein Scope einem Client nicht als optionaler Scope zugewiesen ist und der Scope trotzdem angefordert wird, gibt Keycloak anstelle eines Access Tokens einen invalid scope Error zurück.

Auf diese Weise können wir die Inhalte der generierten Access Tokens sehr detailliert steuern. Auch die Audience, die in jedem Access Token vorhanden sein sollte, können wir über Scopes und Protocol Mapper in das Token bringen. Über die Nutzung und Konfiguration von Audiences wird es ebenfalls einen gesonderten Beitrag geben.

Falls weiterhin Unklarheiten darüber bestehen, wie die Inhalte der Access Tokens gesteuert werden können, schreibt mir gerne eine Mail oder kontaktiert mich auf LinkedIn oder Instagram 😊 Auch Feedback zu diesem Beitrag nehme ich gerne an.


Let's Connect

Wie ihr sicher wisst, gibt es in der Softwareentwicklung nicht den einen, richtigen Weg. Softwareentwicklung lebt von zahlreichen Ideen und offenem Austausch.

Also schreibt mir ne Mail oder kontaktiert mich auf Instagram/LinkedIn 🤓