main_java

Keycloak Configuration Validator

Utilities für die Validierung der Keycloak-Konfiguration und JWT-Token-Analyse.

Überblick

Dieses Modul enthält wiederverwendbare Komponenten zur Validierung der Konsistenz zwischen:


⏱️ Token-Lebensdauern (Keycloak Realm Setup)

Das KeycloakRealmSetup konfiguriert automatisch optimale Token-Lebensdauern:

Token-Typ Lebensdauer Zweck
Access Token 30 Minuten Verhindert häufige Re-Authentifizierung
Refresh Token 30 Minuten (Idle) Automatische Verlängerung bei Aktivität
SSO Session Max 10 Stunden Maximum Session-Lebensdauer
Offline Session 30 Tage “Remember Me” Funktionalität

Warum diese Werte?

Problem gelöst: Früher bekamen User direkt nach Login “Session Expired”-Dialoge, weil Default-Token-Lebensdauer zu kurz war (oft nur 1-5 Minuten).


Komponenten

KeycloakConfigValidator

Zentrale Validator-Klasse mit statischen Methoden für verschiedene Validierungsszenarien:

// Rollen-Validierung
Set<String> tokenRoles = Set.of("task-read", "task-write");
Set<String> requiredRoles = Set.of("task-read", "task-write", "task-delete");
RoleValidationResult result = KeycloakConfigValidator.validateRoles(tokenRoles, requiredRoles);

if (!result.isValid()) {
    System.out.println(result.getSummary());
    result.getRecommendations().forEach(System.out::println);
}

// Audience-Validierung
Set<String> tokenAudiences = Set.of("jeeeraaah-backend", "account");
AudienceValidationResult audResult = KeycloakConfigValidator.validateAudience(
    tokenAudiences, "jeeeraaah-backend");

// Naming-Consistency Check
Set<String> roles = Set.of("task-read", "taskgroup-read"); // Inkonsistent!
NamingConsistencyResult namingResult = 
    KeycloakConfigValidator.validateRoleNamingConsistency(roles);

// Token-Lifetime Validierung
TokenLifetimeValidationResult lifetimeResult = 
    KeycloakConfigValidator.validateTokenLifetime(300, 1800);

JwtTokenParser

Lightweight JWT-Parser für Debugging und Validierung (ohne externe Dependencies):

String token = "eyJhbGc..."; // JWT Token
TokenInfo tokenInfo = JwtTokenParser.parseToken(token);

System.out.println("Issuer: " + tokenInfo.getIssuer());
System.out.println("Subject: " + tokenInfo.getSubject());
System.out.println("Audiences: " + tokenInfo.getAudiences());
System.out.println("Roles: " + tokenInfo.getRoles());
System.out.println("Expired: " + tokenInfo.isExpired());
System.out.println("Remaining: " + tokenInfo.getRemainingLifetimeSeconds() + "s");

Hinweis: Dieser Parser ist nur für Debugging gedacht. Für Produktiv-Validierung sollten robuste JWT-Bibliotheken wie jose4j oder nimbus-jose-jwt verwendet werden.

ValidationReport

Kombiniert alle Validierungen in einem umfassenden Report:

ValidationReport report = ValidationReport.builder()
    .roleValidation(roleResult)
    .audienceValidation(audResult)
    .namingConsistency(namingResult)
    .tokenLifetime(lifetimeResult)
    .build();

if (!report.isFullyValid()) {
    System.out.println(report.getDetailedReport());
}

Integration im jeeeraaah-Backend

Das Backend-Modul app/jeeeraaah/backend/api/ws_rs verwendet diese Utilities für:

1. Startup-Validierung

KeycloakConfigurationValidator scannt beim Start alle REST-Services und validiert:

2. Admin-Endpoint

KeycloakValidationEndpoint bietet REST-Endpoints für Runtime-Validierung:

# Konfiguration neu validieren
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:9080/jeeeraaah/admin/keycloak/validate-config

# Konkreten Token validieren
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"token": "eyJhbGc..."}' \
  http://localhost:9080/jeeeraaah/admin/keycloak/validate-token

Sicherheit: Diese Endpoints erfordern die Rolle task-group-admin.

Häufige Probleme und Lösungen

Problem: “Missing required role(s)”

Ursache: Token enthält nicht alle Rollen, die Backend erwartet.

Lösung:

# Rolle in Keycloak erstellen
docker exec keycloak /opt/keycloak/bin/kcadm.sh create roles \
  -r jeeeraaah-realm -s name=task-read

# Rolle dem User zuweisen
docker exec keycloak /opt/keycloak/bin/kcadm.sh add-roles \
  -r jeeeraaah-realm --uusername r-uu --rolename task-read

Problem: “Token audience does not contain expected value”

Ursache: Keycloak-Client hat keinen Audience-Mapper konfiguriert.

Lösung:

  1. Keycloak Admin Console → Clients → jeeeraaah-frontend
  2. Client scopes → jeeeraaah-frontend-dedicated → Add mapper
  3. By configuration → Audience
  4. Included Custom Audience = jeeeraaah-backend

Problem: “Naming inconsistencies detected”

Ursache: Gemischte Namenskonventionen (z.B. taskgroup-read vs. task-group-read).

Lösung: Standardisierung auf eine Konvention:

Problem: “Token lifetime too short”

Ursache: Access Token Lifetime < 60 Sekunden.

Lösung:

  1. Keycloak Admin Console → Realm Settings → Tokens
  2. Access Token Lifespan = 5 minutes (empfohlen)
  3. Refresh Token Lifespan = 30 minutes

Testing

Umfassende Unit-Tests sind vorhanden:

mvn test -pl lib/keycloak_admin

Dependencies

Minimale Dependencies für maximale Wiederverwendbarkeit:

Keine externen JWT-Bibliotheken → Einfacher Parser für Debugging-Zwecke.

Lizenz

Internes r-uu Projekt