Utilities für die Validierung der Keycloak-Konfiguration und JWT-Token-Analyse.
Dieses Modul enthält wiederverwendbare Komponenten zur Validierung der Konsistenz zwischen:
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).
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);
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.
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());
}
Das Backend-Modul app/jeeeraaah/backend/api/ws_rs verwendet diese Utilities für:
KeycloakConfigurationValidator scannt beim Start alle REST-Services und validiert:
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.
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
Ursache: Keycloak-Client hat keinen Audience-Mapper konfiguriert.
Lösung:
jeeeraaah-backendUrsache: Gemischte Namenskonventionen (z.B. taskgroup-read vs. task-group-read).
Lösung: Standardisierung auf eine Konvention:
task-group-read, task-group-write (mit Bindestrichen)Ursache: Access Token Lifetime < 60 Sekunden.
Lösung:
5 minutes (empfohlen)30 minutesUmfassende Unit-Tests sind vorhanden:
mvn test -pl lib/keycloak_admin
Minimale Dependencies für maximale Wiederverwendbarkeit:
Keine externen JWT-Bibliotheken → Einfacher Parser für Debugging-Zwecke.
Internes r-uu Projekt