1. Intro

In diesem Tutorial wird die Einbindung von Keycloak in ein Angular Projekt beschrieben. Zusätzlich wird gezeigt, wie Rollen-basierte Zugriffskontrolle (RBAC) implementiert werden kann.

1.1. Welches Problem löst das Zusammenspiel von Angular und Keycloak?

Die Integration von Keycloak in Angular ermöglicht es, die Authentifizierung und Autorisierung von Benutzern in Angular-Anwendungen zu verwalten. Dadurch können Benutzer sicher auf die Anwendung zugreifen und erhalten nur das Zugriffsreicht auf die Bereiche, für die sie autorisiert sind. Benutzer, die keine Berechtigung haben, können auf geschützte Bereiche nicht zugreifen.

2. Keycloak - Setup

2.1. Schritt 1: Herunterladen

Ein lokaler Keycloak Server muss eingerichtet werden, um die Authentifizierung und Autorisierung zu verwalten. Keycloak herunterladen (unter der Überschrift: Download Keycloak)

Version von Keycloak zum Zeitpunkt der Dokumentation: 26.1.4

Die heruntergeladene ZIP-Datei muss entpackt werden. Anschließend wird der Ordner geöffnet, bzw. im Terminal in den Folder navigiert und mittels folgenden Kommando gestartet:

command keycloak
Figure 1. Kommando
Linux:
bin/kc.sh start-dev
Windows:
bin\kc.bat start-dev

2.2. Schritt 2: Erstellen eines Administrators

Folgend muss im Browser zu localhost:8080 navigiert werden (Keycloak).

Dort öffnet sich bei erster Inbetriebnahme ein Setup Wizard, worin ein Administrativer Benutzer angelegt werden muss. Es müssen die Daten für einen Admin Benutzer eingegeben werden.

admin create
Figure 2. Keycloak-Admin erstellen
Credentials merken!

2.3. Schritt 3: Erstellen eines Realms

Nachdem der Administrator erstellt und sich damit eingeloggt wurde, kann ein Realm für die Applikation erstellt werden.

Oben links befindet sich ein Dropdown Menü, in dem ein neuer Realm erstellt werden kann, wie in Abbildung: Realm erstellen zu sehen.

realm create
Figure 3. Realm erstellen

Nachdem der Create Realm Knopf gedrückt wurde, öffnet sich ein Fenster, worin der Name des Realms eingetragen werden kann.

  • Im Realm name Feld kann ein beliebiger Name verwendet werden. In diesem Beispiel wird frontend als Name des Realms verwendet.

  • Die Option Enabled sollte aktiviert sein, um den Realm bereitzustellen.

  • Um die Einstellungen zu speichern, muss der Create Knopf gedrückt werden.

realm name
Figure 4. Realm Name

2.4. Schritt 4: Erstellen eines Clients

Damit Keycloak in das Angular Projekt eingebunden werden kann, muss ein Client für die Anwendung erstellt werden.

  • Dazu muss auf der linken Seite in den Tab Clients navigiert werden. Daraufhin öffnet sich die Übersicht der Clients.

  • Am oberen Ende befindet sich ein Create client Knopf, welcher die Konfiguration eines neuen Clients startet.

client overview
Figure 5. Client erstellen

Man durchläuft nun drei Schritte zur Konfiguration des Clients.


Der erste Schritt zur Konfiguration des Clients ist die Vergabe eines Namens und einer ID in den folgenden Eingabefeldern. Zudem kann die verwendete Technologie angegeben werden (SAML oder OpenID Connect).

  • Client type: Wir verwenden OpenID Connect, da dieses speziell für Webanwendungen entwickelt wurde.

  • Client ID: Eine beliebige ID für den Client - muss jedoch unique im jeweiligen Realm sein. In unserem Beispiel tutorial-keycloak.

  • Name: Ein beliebiger Name für den Client. In unserem Beispiel tutorial-keycloak.

  • Description: Es kann zusätzlich eine Beschreibung angegeben werden.

  • Always display in UI: In unserem Beispiel ausgeschalten, da es nicht nötig ist.

client names
Figure 6. Konfiguration des Namens/ID/Technologie

Klickt man auf Next, öffnen sich weitere Konfigurationsmöglichkeiten.

Erklärung der einzelnen Einstellungsmöglichkeiten
  • Client authentication: Wenn aktiviert, benötigt der Client ein Client Secret oder einen Public Key, um sich bei Keycloak zu authentifizieren. Der Client ist nicht mehr öffentlich zugänglich. Diese Option wird oft bei Server und Backend-Services verwendet.

  • Authorization: Ermöglicht erweiterte Autorisierungsfunktionen, wie die Verwaltung von Rollen und Zugriffsrechten für Clients und Benutzer.

  • Authentication flow:

    • Standard Flow: Für Webanwendungen, bei denen Benutzer einen Login durchlaufen müssen.

    • Direct Access Grants: Für Clients, die direkt mit Benutzeranmeldedaten (wie in mobilen Apps) einen Token anfordern.

    • Implicit flow: Für Single-Page Applications (SPAs), bei denen das Token direkt im Frontend vergeben wird.

    • Service accounts roles: Für Backend-Services, die ohne Benutzerinteraktion rollenbasierte Zugriffe benötigen.

    • OAuth 2.0 Device Authorization Grant: Für Geräte mit eingeschränkter UI (z. B. Smart TVs), bei denen die Authentifizierung auf einem anderen Gerät erfolgt.

    • OIDC CIBA Grant: Für asynchrone Authentifizierung über einen separaten Kanal (z. B. mobile Apps, Authenticator Apps…​).

client config
Figure 7. Erweiterte Konfiguration des Clients

Klickt man erneut auf Next, landet man im letzten Schritt der Konfiguration.

Hier müssen die Routen des Clients konfiguriert werden.

  • Root URL: Die URL der Angular-Anwendung. In unserem Beispiel das lokale Angular-Projekt http://localhost:4200.

  • Home URL: Die URL, auf die der Benutzer nach dem Login weitergeleitet wird. Wir senden den Benutzer auf die Startseite http://localhost:4200.

  • Valid redirect URIs: Weitere zulässige URLs, auf die der Benutzer weitergeleitet werden kann. In unserem Beispiel *. Wir nehmen somit grundsätzlich alle URLs an.

  • Valid post logout redirect URIs: URLs, auf die der Benutzer nach dem Logout weitergeleitet werden kann. Wir haben keine Eingabe, somit auch keinen Zugriff nach dem Logout.

  • Web origins (CORS): Die URL des Clients, von dem aus die Anfragen an Keycloak gesendet werden. In unserem Beispiel verwenden wir * aus Testzwecken. Sollte in Produktionsumgebungen jedoch auf die tatsächliche URL des Clients gesetzt werden.

client routes
Figure 8. Konfiguration der Routen

Nach diesem Schritt klicken wir unten auf Save.


Die Konfiguration ist somit erledigt.

Schlussendlich wird eine Übersicht zu gesetzter Konfiguration angezeigt. Dort können die Einstellungen angepasst werden.

client overview config
Figure 9. Client Konfiguration Übersicht

Dieses Fenster können wir vorerst überspringen und unten auf Save drücken. Der Client wurde somit fertig konfiguriert.


2.5. Schritt 5: Rollen einrichten

Um eine Role-based-Authorization-Control (RBAC) zu ermöglichen, müssen Rollen erstellt werden, welche den Benutzern später zugeordnet werden.

Dazu navigieren wir erneut auf den Clients Tab auf der linken Seite, wählen einen Client aus und klicken darin auf den Tab Roles. Die Maske sollte aussehen, wie in Abbildung Roles Tab.

Clients → Client auswählen → Roles Tab.

Darin befindet sich der Knopf Create role, welcher die Erstellung einer neuen Rolle einleitet.

client roles
Figure 10. Roles Tab

Es kann nun der Name der Rolle im Feld Role name eingegeben werden. In unserem Beispiel erstellen wir zwei Rollen: admin und user.

client roles config
Figure 11. Role erstellen

Nachdem die jeweiligen Rollen gespeichert wurden, sollten diese in der Übersicht ersichtlich sein.

roles overview
Figure 12. Roles Tab

2.6. Schritt 6: Benutzer erstellen

Damit man sich mit einem Benutzer in der Angular-Anwendung einloggen kann, müssen diese zuvor erstellt werden. Die nötigen Rollen können den Benutzern im Anschluss zugewiesen werden.

Um einen Benutzer zu erstellen, wechselt man auf der linken Seite auf den Users Tab. Dort klickt man auf den Create new user Knopf, wodurch die Konfiguration der Benutzer gestartet wird.

user
Figure 13. Users Tab

Folgende Felder müssen nun ausgefüllt werden:

  • Username: Der Benutzername des Benutzers. In unserem Beispiel admin-user und für einen weiteren Benutzer user-user. Mit diesem Benutzernamen wird sich später in der Angular-Anwendung eingeloggt.

  • Email: Die E-Mail-Adresse des Benutzers. Kann frei gewählt werden.

  • First Name: Der Vorname des Benutzers. Kann frei gewählt werden.

  • Last Name: Der Nachname des Benutzers. Kann frei gewählt werden.

  • Groups: Der Benutzer kann vordefinierten Gruppen zugeordnet werden, die beispielsweise bereits Rollen definiert haben. In unserem Beispiel lassen wir dies leer.

Nach dem Ausfüllen auf Create drücken.

user config
Figure 14. Erstellen eines Benutzers

Nachdem beide Benutzer erstellt wurden, sollte die Übersicht so aussehen:

user overview
Figure 15. Users Tab - Übersicht

2.7. Schritt 7: Credentials setzen

Für beide Benutzer müssen die Credentials gesetzt werden. Dazu klickt man auf einen Benutzer und wechselt innerhalb des Benutzers in den Credentials Tab.

Innerhalb dessen befindet sich ein Set password Knopf, wodurch ein neues Passwort gesetzt werden kann.

credentials
Figure 16. Credentials Tab

Das eingegebene Passwort muss später beim Einloggen auf der Angular-Applikation verwendet werden.

  • Der Schalter Temporary sollte ausgeschaltet werden, da sonst beim nächsten Login das Passwort geändert werden muss.

  • Danach auf Save klicken.

Das Passwort wurde somit für den Benutzer gesetzt.

credentials input
Figure 17. Passwort setzen

Für den jeweiligen Benutzer sollte das gesetzte Passwort zu sehen sein, wie in Abbildung Credentials Tab - Passwort gesetzt.

save password
Figure 18. Credentials Tab - Passwort gesetzt

2.8. Schritt 8: Rollen den Benutzern zuordnen

Den Benutzern müssen nun die Rollen zugeordnet werden. Dazu klickt man auf einen beliebigen Benutzer und wechselt innerhalb des Benutzers in den Role mapping Tab.

Dort befindet sich am oberen Ende ein Assign role Knopf, wodurch die Rollen dem Benutzer zugewiesen werden können.

user roles
Figure 19. Role mapping Tab

Nachdem der Knopf gedrückt wurde, öffnet sich ein Fenster, in dem die Rollen ausgewählt werden können. In unserem Beispiel wählen wir für den admin-user die Rolle admin und für den user-user die Rolle user.

Diese Rollen können in der Suchleiste gefunden und ausgewählt werden.

user role assignment
Figure 20. Rollen zuweisen
Die Keycloak Konfiguration ist somit fertig und wir können mit der Angular-Integration fortfahren.

3. Angular

3.1. Prerequisites

  • Node.js

  • Angular CLI

3.2. Schritt 1: Angular Projekt erstellen

Angular Version dieser Dokumentation: 19.2.5

Das Projekt kann über die CLI erstellt werden:

ng new <name> (1)
1 name: Name des Projekts

Bei der Erstellung des Projekts wird man gefragt, welche Art von Stylesheets man verwenden möchte. In diesem Beispiel wird SCSS verwendet, kann jedoch je nach Präferenz angepasst werden.


Das Projekt kann nun über die CLI ausprobiert werden, mittels folgenden Command.

ng serve

Das Basisprojekt kann nun unter localhost:4200 aufgerufen werden, und sollte in etwa so aussehen:

angular intro page
Figure 21. Angular Basisprojekt

3.3. Schritt 2: Erstellen der Komponenten

Für die Angular-Applikation werden zur Demonstration zwei Komponenten erstellt: admin und user.
Damit die Komponenten erstellt werden können, wird folgender Befehl in der CLI ausgeführt (Pfad: src/app):

ng g c admin
ng g c user

Die Projektstruktur sollte nach dem Erstellen der Komponenten so aussehen:

angular structure
Figure 22. Angular Struktur

Damit wir später den Unterschied sehen, wird in den Komponenten admin und user ein einfacher Text hinzugefügt.

admin.component.html
<h1>Diese Seite ist nur für Admins zugänglich</h1>
user.component.html
<h1>Diese Seite ist für User zugänglich</h1>

3.4. Schritt 3: Keycloak in Angular einbinden

Zuerst muss die Keycloak library installiert werden, um Keycloak in Angular zu integrieren.
Dazu ist folgendes Kommando nötig:

npm install keycloak-angular keycloak-js

Nachdem die Installation abgeschlossen ist, kann Keycloak in Angular eingebunden werden.
Dazu muss eine neue Typescript Datei im Pfad src erstellt werden.
Diese ist für die Konfiguration von der Keycloak-Integration zuständig.

Name der Datei: keycloak-init.ts

Diese enthält Folgendes:

import Keycloak from 'keycloak-js';
import { KeycloakService } from 'keycloak-angular';

export function initializeKeycloak(keycloak: KeycloakService): () => Promise<boolean> {
  return (): Promise<boolean> =>
    keycloak.init({
      config: {
        url: 'http://localhost:8080', (1)
        realm: 'frontend', (2)
        clientId: 'tutorial-keycloak', (3)
      },
      initOptions: {
        onLoad: 'login-required', (4)
      },
    });
}
1 URL des Keycloak Servers, in unserem Fall der lokale Server http://localhost:8080.
2 Name des Realms, der vorhin vergeben wurde (frontend).
3 ID des Clients, die vorhin vergeben wurde (tutorial-keycloak).
4 login-required bedeutet, dass der Benutzer beim Laden der Anwendung automatisch zur Login-Seite weitergeleitet wird, sofern keine Session besteht.

Zudem muss die Datei src/app/app.config.ts angepasst werden, wodurch die Keycloak-Integration erst erfolgt.

Vorher:

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
        provideZoneChangeDetection({ eventCoalescing: true }),
        provideRouter(routes)]
};

Nachher:

import {APP_INITIALIZER, ApplicationConfig, importProvidersFrom, provideZoneChangeDetection} from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import {KeycloakAngularModule, KeycloakService} from 'keycloak-angular';
import {initializeKeycloak} from '../keycloak-init';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    importProvidersFrom(KeycloakAngularModule), (1)
    KeycloakService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializeKeycloak,
      deps: [KeycloakService],
      multi: true
    }
  ]
};
1 Ab diesem Punkt erfolgen die Änderungen. Die KeycloakAngularModule wird importiert und der KeycloakService wird als Provider hinzugefügt. Zudem wird die APP_INITIALIZER Konstante hinzugefügt, welche die Keycloak-Initialisierung startet. Dadurch wird Keycloak beim Start der Angular-Applikation initialisiert.

Wenn man nun die Angular-Applikation (localhost:4200) öffnet, wird man auf die Keycloak Login Seite weitergeleitet.

keycloak login
Figure 23. Keycloak Login

Man kann sich nun mit den in Keycloak angelegten Benutzern mit den hinzugefügten Credentials einloggen.
Angular ist nun richtig aufgesetzt. Im folgenden Abschnitt geht es darum, die Routen nur mit bestimmten Rollen zugänglich zu machen.

4. Erstellen der Routen & RBAC

Damit die jeweiligen Komponenten von unbefugtem Zugriff geschützt sind, müssen die Routen und die Rollenüberprüfungen entsprechend konfiguriert werden.

4.1. Schritt 1: Erstellen eines Guards

Als Erstes muss ein Guard erstellt werden, welcher die von Keycloak bereitgestellten Rollen überprüft.

Dieser wird im Pfad src/app/auth mittels folgendem Kommando erstellt:

Beim Erstellen mittels CLI gibt es die Möglichkeiten canActivate, canActivateChild, canLoad, und canDeactivate. Wir brauchen hier nur canActivate.
ng g g keycloak

Im Guard File keycloak.guard.ts muss folgendes eingefügt werden:

import {ActivatedRouteSnapshot, CanActivate, CanActivateFn, RouterStateSnapshot, UrlTree} from '@angular/router';
import {Injectable} from '@angular/core';
import {KeycloakService} from 'keycloak-angular';
import {Observable} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class KeycloakGuard implements CanActivate {

  constructor(private keycloakService: KeycloakService) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    const requiredRoles = next.data['roles']; (1)

    if (!Array.isArray(requiredRoles) || requiredRoles.length === 0) {
      return true; (2)
    }

    return requiredRoles.every((role) => this.keycloakService.getUserRoles().includes(role)); (3)
  }
}
1 Hier werden die Rollen, welche von der Route benötigt werden, ausgelesen.
2 Falls die Route keine Rollen benötigt, wird der Zugriff erlaubt.
3 Sollte die Route jedoch Rollen benötigen, wird hier überprüft, ob der eingeloggte Benutzer diese besitzt.
Falls ja, wird der Zugriff erlaubt.

4.2. Schritt 2: Konfigurieren der Routen

Die Komponenten sind jeweils durch gesetzte Routen in der URL erreichbar. Diese Routen müssen nun so konfiguriert werden, dass sie nur für bestimmte Rollen zugänglich sind.

Die Datei app.routes.ts erhält somit folgende Anpassungen:

import {Routes} from '@angular/router';
import {AdminComponent} from './admin/admin.component';
import {KeycloakGuard} from './auth/keycloak.guard';
import {UserComponent} from './user/user.component';

export const routes: Routes = [
    {
        path: 'admin', (1)
        component: AdminComponent, (2)
        canActivate: [KeycloakGuard], (3)
        data: { roles: ['admin'] } (4)
    },
    {
        path: 'user', (1)
        component: UserComponent, (2)
        canActivate: [KeycloakGuard], (3)
        data: { roles: ['user'] } (4)
    }
];
1 Hier wird die Route definiert, unter der die Komponente erreichbar ist.
2 Die Komponente, die bei Aufruf der Route angezeigt wird.
3 Der Guard, der überprüft, ob der Benutzer die benötigten Rollen besitzt.
4 Die Rollen, die für den Zugriff auf die Route benötigt werden.

4.3. Schritt 3: Anpassen der App-Komponente

Damit der Angular Router die Komponenten ausgeben kann, muss die app.component.html angepasst werden:

<h1>Tutorial über Angular & Keycloak - RBAC</h1>

<button (click)="goToAdmin()"> (1)
  <p>Admin</p>
</button>
<button (click)="goToUser()"> (2)
  <p>User</p>
</button>
<button (click)="logout()"> (3)
  <p>Logout</p>
</button>

<router-outlet></router-outlet> (4)
1 Knopf, um auf die Admin Seite zu navigieren.
2 Knopf, um auf die User Seite zu navigieren.
3 Knopf, um sich vom Keycloak auszuloggen.
4 Der Router-Outlet dient als Einstiegspunkt für die gerouteten Komponenten.
Der Router fügt die Komponenten an dieser Stelle ein.

Die app.component.ts erhält folgende Anpassungen:

import { Component } from '@angular/core';
import {Router, RouterOutlet} from '@angular/router';
import {MatToolbar} from '@angular/material/toolbar';
import {MatIcon} from '@angular/material/icon';
import Keycloak from 'keycloak-js';
import {KeycloakService} from 'keycloak-angular';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet, MatToolbar, MatIcon],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent {
  title = 'angular-rbac-keycloak';

  constructor(private keycloak: KeycloakService, (1)
              private router: Router) {
  }

  logout() {
    this.keycloak.logout(); (2)
  }

  goToAdmin() {
    this.router.navigate(['admin']); (3)
  }

  goToUser() {
    this.router.navigate(['user']); (4)
  }
}
1 An dieser Stelle erfolgt die Initialisierung/Dependency Injection des KeycloakService und des Routers.
2 Der Logout-Button ruft die Methode logout() auf, welche den Benutzer aus dem Keycloak ausloggt.
3 Der Button für die Admin-Seite ruft die Methode goToAdmin() auf, welche den Benutzer auf die Admin-Seite weiterleitet.
4 Der Button für die User-Seite ruft die Methode goToUser() auf, welche den Benutzer auf die User-Seite navigiert.

Über den KeycloakService kann auch direkt auf die User-Roles zugegriffen werden, sollten beispielsweise Funktionen nur mit bestimmten Rollen benutzt werden können.

Verwendung des KeycloakService
constructor(private keycloak: KeycloakService,
            private router: Router) {
    keycloak.getUserRoles() (1)
}
1 Die getUserRoles()-Methode liefert die Rollen des eingeloggten Users.

5. Demo

Wenn wir die Anwendung nun ausprobieren und uns mit den Admin Credentials einloggen, können wir auf die Admin Seite zugreifen, während wir mit den User Credentials nur auf die User Seite zugreifen können.

  • Admin-Knopf: Funktioniert nur, wenn man sich mit den Admin Credentials einloggt.

  • User-Knopf: Funktioniert nur, wenn man sich mit den User Credentials einloggt.

admin login
Figure 24. Demo Admin
user login
Figure 25. Demo User
Die Applikation kann nun um gewünschte Funktionalitäten erweitert werden, die nur mit bestimmten Rollen zugänglich sind.