Zum Inhalt

Key Rotation und REST-API

Ziel

In dieser Aufgabe lernen Sie wichtige operative Aspekte von Keycloak kennen. Sie werden Realm-Keys verstehen und eine sichere Key-Rotation durchführen, um die Sicherheit Ihrer Keycloak-Instanz zu gewährleisten. Zusätzlich erhalten Sie praktische Erfahrung mit der Keycloak Admin REST API für die Automatisierung von Benutzerverwaltungsaufgaben.

Hilfsmittel

  • Versuchen Sie, die unten stehenden Aufgaben mit Hilfe der Folien eigenständig zu lösen.
  • Sollten Sie dabei Probleme haben, finden Sie bei jeder Aufgabe einen ausklappbaren Block, in dem der Lösungsweg beschrieben wird.

Vorbereitung

Starten Sie eine Keycloak-Instanz, falls nicht bereits eine läuft.

Docker-compose-Datei
  • Erstellen Sie eine Datei docker-compose.yml
    services:
        postgres:
            image: postgres
            environment:
                POSTGRES_USER: keycloak
                POSTGRES_PASSWORD: secret
                POSTGRES_DB: keycloak
        keycloak:
            image: quay.io/keycloak/keycloak:latest
            environment:
                KC_BOOTSTRAP_ADMIN_USERNAME: admin
                KC_BOOTSTRAP_ADMIN_PASSWORD: admin
                KC_DB: postgres
                KC_DB_URL_HOST: postgres
                KC_DB_USERNAME: keycloak
                KC_DB_PASSWORD: secret
            command:
            - start-dev
            - "--hostname=https://keycloak.code-{ZAHL}.labs.corewire.de"
            - "--proxy-headers=xforwarded"
            depends_on: [ "postgres" ]
            labels:
            - "traefik.enable=true"
            - "traefik.http.routers.keycloak.rule=Host(`keycloak.code-{ZAHL}.labs.corewire.de`)"
            - "traefik.http.services.keycloak.loadbalancer.server.port=8080"
            networks:
            - default
            - proxy
    
        mail:
            # Use to display mails (txt/html) in the browser
            # Port 1025 -> SMTP-Server
            # Port 8025 -> WebUI
            image: maildev/maildev:2.1.0
            ports:
            - "8025:8025"
            environment:
            - MAILDEV_INCOMING_USER=smtp_user
            - MAILDEV_INCOMING_PASS=pass
            - MAILDEV_WEB_PORT=8025
            networks:
            - default
            - proxy
            labels:
            - "traefik.enable=true"
            - "traefik.http.routers.mail.rule=Host(`mail.code-{ZAHL}.labs.corewire.de`)"
            - "traefik.http.services.mail.loadbalancer.server.port=8025"
            healthcheck:
                disable: true
    networks:
        proxy:
            external: true
    
  • Ersetzen Sie {ZAHL}
  • Starten Sie die Keycloak-Instanz mit docker-compose up -d
  • Warten Sie kurz. Nach spätestens 30 Sekunden sollte Sie unter folgendem Link ereichbar sein
    https://keycloak.code-{ZAHL}.labs.corewire.de
    

Aufgabe 1 - Realm Key Rotation

1.1: Keys verstehen und untersuchen

  • Erstellen Sie einen neuen Realm namens key-demo
  • Erstellen Sie einen Testbenutzer und loggen Sie sich mit diesem in einem privaten Tab über die Account-Konsole ein (Browser-Tab offen lassen)
  • Navigieren Sie zu Realm Settings > Keys und untersuchen Sie die vorhandenen Keys:
    • Notieren Sie sich die Kid und den Provider des aktiven HS512 Keys
  • Gehen Sie auf den Tab Add provider
  • Klicken Sie auf den Provider des HS512-Keys. Notieren Sie sich die Priorität

1.2: Key-Rotation durchführen

  • Klicken Sie auf Add providers und wählen Sie HMAC Generated
  • Setzen Sie die Priorität auf 100
  • Speichern Sie und überprüfen Sie, dass der neue Provider als aktiv markiert wird
  • Löschen Sie den alten Provider

1.3: Key-Rotation testen

  • Laden Sie den privaten Tab mit dem angemeldeten Nutzer neu.
  • Sie sollten nun ausgeloggt sein, weil der Session-Token nicht mehr verifiziert werden kann.
  • Wiederholen Sie Schritt 1.2 und 1.3, aber so, dass die Session nicht invalidiert wird.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
  1. Erstellen Sie erneut einen Key-Provider mit gleicher oder höherer Priorität
  2. Setzen Sie den alten Key-Provider auf Inaktiv. (Active=false, Enabled=true)
  3. Laden Sie den privaten Tab neu. Durch die Nutzer-Interaktion wird die Session mit dem neuen Key signiert
  4. Löschen oder deaktivieren Sie nun den alten Key.
  5. Laden Sie den privaten Tab erneut neu. Sie sollten weiterhin eingeloggt sein.

Aufgabe 2 - REST API Benutzerverwaltung

Vorbereitung:

  • Installieren Sie jq mit apt install jq im Terminal.
  • Erhöhen Sie die Access Token Lifespan der admin-cli
    • Gehen Sie auf den admin-cli Client
    • Advanced > Advanced Settings
    • Setzen Sie die Access Token Lifespan von 1 Minute auf 15 Minuten.

2.1: Authentifizierung mit der Admin API

Verwenden Sie die Keycloak Admin REST API, um sich zu authentifizieren:

KC_BASE="https://keycloak.code-{ZAHL}.labs.corewire.de"
# Admin Token erhalten
ACCESS_TOKEN=$(curl -s -X POST "${KC_BASE}/realms/master/protocol/openid-connect/token" \
    -d "grant_type=password" \
    -d "client_id=admin-cli" \
    -d "username=admin" \
    -d "password=admin" | jq -r '.access_token')

echo $ACCESS_TOKEN

AUTHZ="Authorization: Bearer ${ACCESS_TOKEN}"
# Authentifizierung testen durch Auflisten der Realms
curl -s -H "${AUTHZ}" "${KC_BASE}/admin/realms" | jq '.[].realm'

Validierung:

  • Sie sollten eine Liste der Realm-Namen sehen, einschließlich "master"
  • Speichern Sie das ACCESS_TOKEN für weitere Anfragen

2.2: Benutzer über API erstellen

Erstellen Sie einen neuen Benutzer über die REST API:

# Neuen Benutzer erstellen
curl -X POST -H "${AUTHZ}" -H 'Content-Type: application/json' \
    "${KC_BASE}/admin/realms/master/users" \
    -d '{
        "username": "apiuser",
        "firstName": "API",
        "lastName": "User",
        "email": "apiuser@example.com",
        "enabled": true
    }'

# Benutzer-Passwort setzen
USER_ID=$(curl -s -H "${AUTHZ}" "${KC_BASE}/admin/realms/master/users?username=apiuser" | jq -r '.[0].id')

curl -X PUT -H "${AUTHZ}" -H 'Content-Type: application/json' \
    "${KC_BASE}/admin/realms/master/users/${USER_ID}/reset-password" \
    -d '{
        "type": "password",
        "value": "password123",
        "temporary": false
    }'

# Benutzererstellung überprüfen
curl -s -H "${AUTHZ}" "${KC_BASE}/admin/realms/master/users?username=apiuser" | jq

2.3: Rollen erstellen und zuweisen

Erstellen Sie eine neue Rolle und weisen Sie sie dem Benutzer zu:

# Neue Rolle erstellen
curl -X POST -H "${AUTHZ}" -H 'Content-Type: application/json' \
    "${KC_BASE}/admin/realms/master/roles" \
    -d '{
        "name": "api-tester",
        "description": "Rolle für API-Test-Benutzer"
    }'

# Rollendetails abrufen
ROLE_ID=$(curl -s -H "${AUTHZ}" "${KC_BASE}/admin/realms/master/roles/api-tester" | jq -r '.id')

# Rolle dem Benutzer zuweisen
curl -X POST -H "${AUTHZ}" -H 'Content-Type: application/json' \
    "${KC_BASE}/admin/realms/master/users/${USER_ID}/role-mappings/realm" \
    -d '[{
        "id": "${ROLE_ID},
        "name": "api-tester"
    }]'

# Rollenzuweisung überprüfen
curl -s -H "${AUTHZ}" "${KC_BASE}/admin/realms/master/users/${USER_ID}/role-mappings" | jq

2.4: Validierung und Tests

Überprüfen Sie die erstellten Ressourcen in der Admin-Console

Erwartete Ergebnisse:

  • Benutzer apiuser sollte im Realm existieren
  • Benutzer sollte die Rolle api-tester zugewiesen haben