Authorization code flow Intro

Authorization Code Flow

Herzlich willkommen in der Welt der sicheren Authentifizierung! In einer Zeit, in der die Online-Sicherheit eine immer größere Rolle spielt, präsentiere ich  Ihnen heute eine Lösung: den Authorization Code Flow mit Keycloak. Stellen Sie sich vor, Sie könnten die Sicherheitsstandards Ihrer Anwendung deutlich anheben, ohne sich in komplexe Kodierungsprozesse vertiefen zu müssen. Genau das ermöglicht unsere neueste Spring Boot Keycloak-Demo-Anwendung, die ich unter GitHub – zeus-keycloak-demo bereitstelle. Tauchen Sie in die faszinierende Welt der Authentifizierungsflüsse ein und entdecken Sie, wie der OAuth 2.0 Authorization Code Flow Ihren Nutzern nicht nur Sicherheit, sondern auch Komfort bietet

Die unter GitHub – zeus-keycloak-demo vorliegende Spring Boot Keycloak-Demo-Anwendung authorization-code-flow demonstriert die Implementierung des Standard-Authentifizierungsflusses von Keycloak, der auf dem OAuth 2.0 Authorization Code Flow basiert. Voraussetzung ist eine installierte und laufende Keycloak-Instanz, wie im Workshop beschrieben. Sollte das Thema komplett neu für Sie sein, starten Sie am Besten hier: Einstieg in Keycloak

Dieser Flow ist speziell dafür konzipiert, Client-Anwendungen einen sicheren delegierten Zugriff auf Serverressourcen im Auftrag des Endnutzers zu ermöglichen. Durch die Verwendung von Authentifizierungscodes statt direkter Übertragung von Benutzerdaten, bietet dieser Flow einen erhöhten Schutz gegenüber Angriffen wie Cross-Site Request Forgery (CSRF).

Das Prinzip ist einfach, aber effektiv: Ein Nutzer wird aufgefordert, sich bei Keycloak zu authentifizieren. Nach erfolgreicher Authentifizierung wird ein einmaliger Authentifizierungscode generiert und an die Client-Anwendung zurückgesandt. Dieser Code kann dann gegen ein Access-Token, ein Refresh-Token und ein ID-Token eingetauscht werden. Mit dem Access-Token kann die Anwendung im Namen des Nutzers auf geschützte Ressourcen zugreifen. Das Refresh-Token wird verwendet, um das Access-Token zu erneuern, ohne dass der Nutzer sich erneut authentifizieren muss. Das ID-Token, ein JWT (JSON Web Token), enthält Identitätsinformationen über den Nutzer und wird häufig zur Authentifizierung und zur Sitzungsvalidierung in der Anwendung verwendet. So kann die Anwendung nicht nur auf Ressourcen zugreifen, sondern erhält auch bestätigte Informationen über die Identität des Nutzers.

Authorization Code Flow: Eine Spring Boot Demo-Application – https://localhost:8081

Authorization Code Flow Demo Application

Authorization code flow – Step by Step

Authorization code flow

Authorization code flow

Im Kontext unseres Beispiels:

  • User = Anwenderinnen/Anwender
  • Client/Application = Spring Boot Demo Application
  • IDP = Identity Provider Keycloak

Die Demo-Anwendung authorization-code-flow zielt darauf ab, Entwicklern einen praktischen Leitfaden zu bieten, wie sie den Authorization Code Flow und den Resource Owner Password Credentials Flow in ihren Projekten umsetzen können, um eine sichere und effiziente Benutzerverwaltung zu gewährleisten.

Konfiguration der Projektstruktur und Abhängigkeiten

Die Grundlage unserer Demo-Anwendung ist ein Maven-Projekt, welches das Spring Boot Framework nutzt. Spring Boot erleichtert uns die Konfiguration und das Setup, damit wir uns auf die wichtigen Aspekte der Keycloak-Integration konzentrieren können.

Hier ist ein Überblick über die wesentlichen Teile der `pom.xml`, die für unser Projekt konfiguriert wurden:

  • Spring Boot Starter Parent: Durch die Nutzung des `spring-boot-starter-parent` mit der Version 3.0.4 stellen wir sicher, dass unser Projekt auf der neuesten stabilen Spring Boot Version aufbaut. Dies ermöglicht uns, von den neuesten Features und Verbesserungen zu profitieren.
  • Java-Version: Mit `maven.compiler.source` und `maven.compiler.target` auf Version `17` eingestellt, verwenden wir eine aktuelle Version mit stabilen Features der Java-Sprache, was uns verbesserte Performance und eine modernere Syntax bietet.
  • Spring Boot Starter Web: Diese Abhängigkeit zieht alles Notwendige für die Erstellung einer Webanwendung heran, inklusive Tomcat als embedded Servlet Container und Spring MVC.
  • Spring Boot Starter Security und Spring Security OAuth2 Resource Server: Diese Pakete bieten die Tools, um unsere Anwendung abzusichern und den Schutz unserer Endpunkte über OAuth2 Token zu gewährleisten
  • Spring Boot Starter OAuth2 Client: Damit wird die Anwendung um die Fähigkeit erweitert, sich als OAuth2-Client zu authentifizieren, was für die Kommunikation mit Keycloak notwendig ist.
  • Lombok: Durch diese Bibliothek reduzieren wir den zu schreibenden Boilerplate-Code erheblich, was unsere Anwendung übersichtlicher und wartbarer macht.
  • Spring Boot Maven Plugin: Dieses Plugin hilft uns, die Anwendung zu verpacken und auszuführen.

Der Controller der Demo-Anwendung

Unsere Demo-Anwendung verwendet einen Spring-Controller, um verschiedene Endpunkte für unsere Webanwendung bereitzustellen. Jede Methode im Controller ist einem spezifischen Pfad zugeordnet und definiert, was passiert, wenn ein Benutzer diesen Pfad aufruft.

Basis-Endpunkte

  • @GetMapping("/") Das Root-Verzeichnis der Anwendung leitet einfach zur `index.html` weiter, welche als unsere Startseite fungiert.
  • @GetMapping("/public") Der öffentliche Endpunkt, zu dem jeder Zugang hat, ohne sich authentifizieren zu müssen.
  • @GetMapping("/secured") Ein gesicherter Endpunkt, der nur nach erfolgreicher Authentifizierung erreichbar ist.

Rollenbasierte Zugriffskontrolle

Unsere Anwendung implementiert rollenbasierte Zugriffskontrolle mit benutzerdefinierten Annotations:

  • @GetMapping("/realm-admin-realm-user-only")
    @CustomRolesAllowed({"admin", "user"})
    Dieser Endpunkt ist nur für Benutzer mit den Rollen „admin“oder „user“ im Realm zugänglich.
  • @GetMapping("/realm-admin-only")
    @RealmAdminOnly
    Spezifisch für Realm-Administratoren.
  • @GetMapping("/resource-admin-only")
    @ResourceAdminOnly(resource = "athen", role = "client_admin")
    Hier wird der Zugriff auf Benutzer beschränkt, die in einer bestimmten Resource in diesem Fall client-id „athen“ die Rolle „client_admin“ haben.
  • @GetMapping("/composite-role-endpoint")
    @CompositeRoles({"athen:client_admin", "olymp:admin"})
    Zugänglich für Benutzer, die komplexe Rollenanforderungen erfüllen, hier sowohl „client_admin“ in Client-id „athen“ als auch „admin“ in Realm „olymp“

Logout-Funktionalität

  • @GetMapping("/logout")
    Hier wird der Benutzer ausgeloggt. Die Spring-Security-Infrastruktur kümmert sich darum, den `Authentication`-Kontext zu leeren und die Sitzung zu invalidieren.

Absicherung der Endpunkte durch die Spring Security und TokenUtils Klasse

Die Sicherung der Endpunkte in unserer Anwendung wird durch benutzerdefinierte Annotationen wie @CustomRolesAllowed, @RealmAdminOnly, @ResourceAdminOnly und @CompositeRoles gewährleistet. Diese Annotationen stellen eine effektive Methode dar, um spezifische Sicherheitslogiken zu implementieren. Indem sie direkt in den Controller-Code integriert werden, verbessern sie nicht nur die Lesbarkeit, sondern auch die Wartbarkeit der Zugriffskontrollregeln.

Jede dieser Annotations arbeitet mit der `TokenUtils` – Klasse zusammen, um zu überprüfen, ob der aktuelle Benutzer die erforderlichen Rollen für den Zugriff auf einen Endpunkt besitzt. Dies zeigt die Flexibilität von Spring Security, wenn es um die Erweiterung und Anpassung an komplexe Sicherheitsanforderungen geht.

Diese Klasse ist ein maßgeblicher Bestandteil des Sicherheitssystems der Applikation, da sie verantwortlich für die Auwertung und die Verarbeitung von JWTs (JSON Web Tokens) ist, die von Keycloak für die Authentifizierung und Autorisierung ausgestellt werden. JWTs sind ein integraler Bestandteil moderner Authentifizierungsmechanismen in verteilten Systemen. Ein Token besteht aus drei durch Punkte getrennten Teilen: Header, Payload und Signatur. Die `TokenUtils`-Klasse konzentriert sich auf den Payload, der die relevanten Benutzeransprüche (Claims) enthält

Konfiguration und Initialisierung

Bevor die `TokenUtils` ihre Funktionen ausführen kann, muss sie mit der erforderlichen Konfiguration initialisiert werden. Konfigurationsparameter wie der `externalOauth2Provider` oder Schalter für das Logging werden über `@Value`-Annotationen geladen und steuern das Verhalten der Klasse.

Kernfunktionen

  • Laden und Parsen des Tokens
    Die primäre Aufgabe der Klasse ist das Laden und Parsen des Access Tokens eines Benutzers, um Zugang zu den darin enthaltenen Informationen zu erhalten. Die Methode `loadPayload()` nimmt den Benutzernamen entgegen, lädt den entsprechenden OAuth2AuthorizedClient und extrahiert den Payload aus dem Access Token. Hierbei wird auch geprüft, ob das Token im korrekten Format vorliegt.
  • Rollen- und Rechteprüfung
    Mit Methoden wie `hasAnyRealmRole()`, `hasRealmRole()` und `hasResourceRole()` bietet `TokenUtils` die Möglichkeit, zu überprüfen, ob ein Benutzer bestimmte Rollen oder Rechte besitzt. Diese Funktionen sind entscheidend, um sicherzustellen, dass Benutzer nur auf die für sie bestimmten Ressourcen zugreifen können.
  • Zusätzliche Hilfsmethoden
    Die Klasse stellt weitere Methoden wie `getScopesFromToken()` zur Verfügung, um die Scopes eines Tokens abzurufen. Scopes sind essentiell, um zu bestimmen, auf welche Bereiche der Anwendung der Benutzer Zugriff hat.
  • Logging und Feedback
    `TokenUtils` bietet umfangreiche Logging-Funktionen, um die Token- und Rollendaten eines Benutzers für Debugging und Überwachungszwecke auszugeben. Die Methoden `printUserRolesAndAuthorities()`, `printTokens()` und `printScopes()` dienen dazu, die Token-Informationen in einem lesbaren Format auszugeben.

Anpassung und Erweiterbarkeit

Während die aktuelle Implementierung von `TokenUtils` eine breite Palette von Funktionen abdeckt, ist es möglich und erwartet, dass die Klasse angepasst oder erweitert wird, um spezifische Sicherheitsanforderungen eines Projekts zu erfüllen.

Die TokenUtils-Klasse ist ein unverzichtbares Werkzeug in unserer Anwendung, die mit Keycloak als Authentifizierungsprovider arbeitet und speziell als Teil unserer Demo für Trainingszwecke konzipiert wurde. Sie bietet eine zuverlässige Schnittstelle zum Laden, Parsen und Inspektieren von OAuth2-Token, um die Sicherheitsmechanismen der Anwendung zu unterstützen. Wichtig zu beachten ist, dass das Logging von Token-Informationen ausschließlich zu Trainings- und Testzwecken in einer sicheren Testumgebung empfohlen wird. In einer Produktionsumgebung sollten Token-Informationen aus Sicherheitsgründen nicht geloggt werden, um das Risiko von Datenlecks und anderen Sicherheitsbedrohungen zu minimieren.

Wir sind am Ende unserer Entdeckungsreise angelangt! Sie haben jetzt einen umfassenden Einblick in die Welt des Authorization Code Flows mittels der Spring Boot Keycloak-Demo-Anwendung erhalten. Online-Sicherheit ist kein Hexenwerk, sondern das Resultat sorgfältig entwickelter und implementierter Mechanismen. Mit der Einbindung des Authorization Code Flows in Ihre Projekte können Sie nicht nur die Sicherheit Ihrer Anwendungen erheblich steigern, sondern bieten Ihren Nutzern auch eine komfortable Authentifizierungserfahrung. Ich hoffe, dass dieser Blog-Post für Sie hilfreich war und bin gespannt darauf, wie Sie diese Techniken in Ihren eigenen Projekten umsetzen werden. Bleiben Sie sicher und viel Spaß beim Programmieren!

Mit nur wenigen Anpassungen kann über die Demo-Anwendung auch der Ressource Owner Password Credentials Flow realisiert werden. Das zeige ich im nächsten Beitrag. Einfach wieder reinschauen.