1. Einleitung
Im vergangenen Artikel zu dem Thema (Docker: WildFly Server mit Keycloak) habe ich gezeigt, wie ihr ein Docker Image des WildFly Servers inklusive Keycloak Adapter erzeugen könnt. Wenn allerdings keine Keycloak Instanz parallel läuft, bringt dieser WildFly Container keinen Mehrwert. Ich zeige euch deshalb in diesem Artikel folgendes:
- Wie ihr einen WildFly und Keycloak Container zusammen hochfahrt.
- Wie ihr dabei ein zuvor exportiertes Realm in Keycloak importiert.
- Und abschließend wie ihr die Funktionalität anhand einer Beispielanwendung überprüfen könnt.
2. Docker Compose
Wir nutzen Docker Compose, um beide Container (WildFly mit Keycloak Adapater sowie Keycloak) gemeinsam zu starten und alle relevanten Parameter strukturiert angeben zu können. Dies lässt sich auch per docker run bewerkstelligen, ich persönlich finde es aber schöner hier mit einem Klick in der IDE (IntelliJ) gleich beide benötigten Container zu erzeugen und hochzufahren. In beiden Fällen bekommen wir beim Testen auf localhost
allerdings Schwierigkeiten bei der Kommunikation vom WildFly hin zu Keycloak. Darauf gehe ich später ein.
Es bietet sich an die Sourcen aus GitHub zu clonen, um die folgenden Erläuterungen besser nachvollziehen zu können. Die Sourcen findest du hier auf GitHub: https://github.com/MatthiasPischka/dockering/tree/main/compositions/wildfly-mit-keycloak
Zentrale Anlaufstelle ist die Datei docker-compose.yml
:
version: '3.8' services: keycloak: image: jboss/keycloak:14.0.0 ports: - "8180:8080" environment: KEYCLOAK_USER: admin KEYCLOAK_PASSWORD: admin1234 KEYCLOAK_IMPORT: /tmp/Testrealm.json volumes: - ./tmp:/tmp wildfly: image: matthiaspischka/wildfly-keycloak:24.0.0-14.0.0 ports: - "8080:8080" - "9990:9990" volumes: - ./deployments:/opt/jboss/wildfly/standalone/deployments
2.1 Keycloak Service
Das ist unser Keycloak Server, mit dem der WildFly Server später kommunizieren wird.
- image: Unangepasstes Image von JBoss.
- ports: Wir können den Standard-Port 8080 nicht verwenden, da dieser mit dem des WildFlys kollidiert. Deshalb nutzen wir 8180 nach außen hin.
- environment:
- KEYCLOAK_USER & KEYCLOAK_PASSWORD: Hierdurch legen wir einen Benutzer zur Administration von Keycloak an.
- KEYCLOAK_IMPORT: Wir lesen ein zuvor exportiertes Realm (dazu später mehr) ein. Dadurch können wir uns auf das lokale Testen der jeweiligen Anwendung konzentrieren.
- volumes: Das tmp Verzeichnis wird außerhalb abgelegt, um das exportiere Realm von außen in den Container setzen zu können
2.2 WildFly Service
- image: WildFly Server inklusive Keycloak Adapter (siehe: Docker: WildFly Server mit Keycloak)
- ports: Standard für Anwendungen (8080) und Administration (9990)
- volumes: Hier wird das Deployment-Verzeichnis für Hot Deployments außerhalb des Containers abgelegt, sodass der WildFly auf einfachem Weg mit der Beispielanwendung versorgt werden kann
2.3 Erzeugen und Starten
Entweder klassisch par Konsole:
docker-compose -f docker-compose.yml up -d
Oder zum Beispiel als simple Run Configuration in IntelliJ IDEA:
In beiden Fällen sollten folgende Services aufrufbar sein:
- HTTP Willkommensseite WildFly: http://localhost:8080
- Admin Konsole des WildFlys: http://localhost:9990 (admin / admin1234)
- Keycloak Administration: http://localhost:8180 (admin / admin1234)
3. Testrealm (Keycloak)
Das Realm wurde über die Keycloak Administrationsoberfläche angelegt und anschließend exportiert, damit es nicht jedes Mal zum Testen in einem frischen Keycloak Container konfiguriert werden muss.
Im Wesentlichen umfasst das Realm folgendes:
- clients
testclient
mit der Client-Rolleintern
undhttp://localhost:8080/*
alsvalid redirect Uri
.
- users
testuser
mit Passworttest12
testintern
mit Passworttest12
und zugewiesener Rolleintern
3.1 keycloak.json
Über die Keycloak Verwaltung kann im Bereich Installation (auf Client-Ebene) die Keyloak OIDC JSON
exportiert werden. Diese benötigen wir für alle Anwendungen, die über Keycloak abgesichert werden sollen und die auf dem WildFly mit dem Keycloak Adapter installiert werden sollen.
Bei den zuvor gezeigten Einstellungen sieht der Export wie folgt aus:
{ "realm": "Testrealm", "auth-server-url": "http://localhost:8180/auth/", "ssl-required": "external", "resource": "testclient", "public-client": true, "verify-token-audience": true, "use-resource-role-mappings": true, "confidential-port": 0 }
Entscheidend ist hier der Parameter auth-server-url
, den wir für lokale Tests mit den gezeigten Docker Containern anpassen müssen. Darauf gehe ich gleich gesondert ein.
4. Beispielanwendung
Der Quellcode der im Docker Container installierten Anwendung (jsf2.3-keycloak) ist hier auf GitHub zu finden: https://github.com/MatthiasPischka/java-ee-8-beispiele/tree/master/jsf2.3-keycloak
Es handelt sich dabei um eine simple JSF 2.3 Anwendung mit zwei Seiten. Eine Seite befindet sich im öffentlichen Bereich, die zweite Seite ist per Navigation erreichbar und ist per Keycloak abgesichert. Die Anwendung kann über http://localhost:8080/jsf2.3-keycloak/ geöffnet werden, sofern die gezeigte Docker Composition korrekt hochgefahren ist. Wenn wir jetzt auf den dargestellten Link (zum internen Bereich) klicken, leitet uns der Browser zur Loginmaske von Keycloak um:
Die Beispielanwendung ist so konfiguriert, dass sich ein Benutzer aus dem Testrealm
anmelden muss, dem auch die Rolle intern
zugewiesen ist (das klappt hier mit dem Benutzer testintern
). Erst nach erfolgreicher Anmeldung gelangt der Benutzer zum internen Bereich der Beispielanwendung.
Wie die Anwendung genau zu konfigurieren ist, wird in einem separaten Beitrag beschrieben.
4.1 auth-server-url
Wie bereits erwähnt, können wir beim Testen auf dem localhost
mit Docker Container nicht die von Keycloak vorgegebene URL (http://localhost:8180/auth/) verwenden. Warum ist das so?
- Für die Umleitung zur Loginmaske von Keycloak innerhalb des Browsers wird die genannte URL aus der Konfiguration entnommen und entsprechend ergänzt. Dieser Schritt funktioniert auch noch, wenn der Keycloak Server wie gezeigt im Docker Container läuft. Wir haben von unserem
localhost
Zugriff auf alle freigegebenen Ports der Docker Container. - Problematisch wird es allerdings für den WildFly Server, auf dem die Beispielanwendung installiert ist. Dieser läuft ebenfalls innerhalb eines Docker Containers. Der WildFly Server versucht intern auch über den Keycloak Adapter mit dem Keycloak Server zu kommunizieren. Dazu verwendet der Adapter die selbe Konfiguration und somit den selben Wert für die
auth-server-url
(http://localhost:8180/auth/).Localhost
verweist innerhalb des Containers aber auf das lokale Netzwerk. Der Aufruf kommt also nicht aus dem Container heraus, um über das Host-System auf den Keycloak Container zuzugreifen. Unter Windows kann man einen Trick verwenden. Ändert man dieauth-server-url
auf den Werthttp://gateway.docker.internal:8180/auth/
so wird das Docker Host System, auf dem die Container laufen, angesprochen. Das funktioniert in beiden Fällen:- Der Browser kann
gateway.docker.internal
auflösen, indem die Anfragen an denlocalhost
gerichtet werden - Der WildFly kommt mit seinen Adapter Anfragen aus dem Container heraus uns setzt sie indirekt an das Host System über Port 8180 (Keycloak Container) ab.
- Der Browser kann
Nähere Informationen zum genannten Problem auf dem localhost
lassen sich hier finden: https://docs.docker.com/desktop/windows/networking/
0 Kommentare