A Testcontainers implementation for Keycloak SSO.
As of October 28th 2021, the Keycloak project announced the roadmap for the new Quarkus-based Keycloak-X distribution. I'm working currently already on a Keycloak-X Testcontainers version, which will be also version 2.x of this library. It is planned to provide the version 2.x with Keycloak-X support with the first supported release of Keycloak-X, which will be Keycloak 17. At the same time, version 2.x of this project, will NO MORE support "legacy" Keyclaok (the Wildfly-based distribution).
A first release-candidate of the Keycloak-X based Testcontainer is available via the JitPack repository: https://jitpack.io/#dasniko/testcontainers-keycloak/keycloak-x-SNAPSHOT
Nevertheless, the current 1.x branch will live and be maintained until the Wildfly-based legacy Keycloak distribution is dropped (approx mid 2022). From Keycloak 17, the legacy Keycloak distribution will be marked deprecated, so I will do the same with this library version 1.x branch!
The @Container
annotation used here in the readme is from the JUnit 5 support of Testcontainers.
Please refer to the Testcontainers documentation for more information.
Simply spin up a default Keycloak instance:
@Container
private KeycloakContainer keycloak = new KeycloakContainer();
Use another Keycloak Docker image/version than used in this Testcontainer:
@Container
private KeycloakContainer keycloak = new KeycloakContainer("jboss/keycloak:16.0.0");
Power up a Keycloak instance with one ore more existing realm JSON config files (from classpath):
@Container
private KeycloakContainer keycloak = new KeycloakContainer()
.withRealmImportFile("test-realm.json");
or
.withRealmImportFiles("test-realm-1.json", "test-realm-2.json");
Use different admin credentials than the defaut internal (admin
/admin
) ones:
@Container
private KeycloakContainer keycloak = new KeycloakContainer()
.withAdminUsername("myKeycloakAdminUser")
.withAdminPassword("tops3cr3t");
You can obtain several properties form the Keycloak container:
String authServerUrl = keycloak.getAuthServerUrl();
String adminUsername = keycloak.getAdminUsername();
String adminPassword = keycloak.getAdminPassword();
with these properties, you can create a org.keycloak.admin.client.Keycloak
(Keycloak admin client, 3rd party dependency from Keycloak project) object to connect to the container and do optional further configuration:
Keycloak keycloakAdminClient = KeycloakBuilder.builder()
.serverUrl(keycloak.getAuthServerUrl())
.realm("master")
.clientId("admin-cli")
.username(keycloak.getAdminUsername())
.password(keycloak.getAdminPassword())
.build();
See also KeycloakContainerTest
class.
You have several options to use HTTPS/TLS secured communication with your Keycloak Testcontainer.
Plain Keycloak comes with a default Java KeyStore (JKS) with an auto-generated, self-signed certificate on first use.
You can use this TLS secured connection, although your testcontainer doesn't know of anything TLS-related and returns the HTTP-only url with getAuthServerUrl()
.
In this case, you have to build the auth-server-url on your own, e.g. like this:
String authServerUrl = "https://localhost:" + keycloak.getHttpsPort() + "/auth";
See also KeycloakContainerHttpsTest.shouldStartKeycloakWithDefaultTlsSupport
.
This Keycloak Testcontainer comes with built-in TLS certificate (tls.crt
), key (tls.key
) and Java KeyStore (tls.jks
) files, located in the resources
folder.
You can use this configuration by only configuring your testcontainer like this:
@Container
private KeycloakContainer keycloak = new KeycloakContainer().useTls();
The password for the provided Java KeyStore file is changeit
.
See also KeycloakContainerHttpsTest.shouldStartKeycloakWithProvidedTlsCertAndKey
.
The method getAuthServerUrl()
will then return the HTTPS url.
Of course you can also provide your own certificate and key file for usage in this Testcontainer:
@Container
private KeycloakContainer keycloak = new KeycloakContainer()
.useTls("your_custom.crt", "your_custom.key");
See also KeycloakContainerHttpsTest.shouldStartKeycloakWithCustomTlsCertAndKey
.
The method getAuthServerUrl()
will also return the HTTPS url.
To ease extension testing, you can tell the Keycloak Testcontainer to detect extensions in a given classpath folder. This allows to test extensions directly in the same module without a packaging step.
If you have your Keycloak extension code in the src/main/java
folder, then the resulting classes will be generated to the target/classes
folder.
To test your extensions you just need to tell KeycloakContainer
to consider extensions from the target/classes
folder.
Keycloak Testcontainer will then dynamically generate an exploded "jar file" with the extension code that is then picked up by Keycloak.
private KeycloakContainer keycloak = new KeycloakContainer()
.withExtensionClassesFrom("target/classes");
You may also deploy your extension as a provider module.
private KeycloakContainer keycloak = new KeycloakContainer()
.withProviderClassesFrom("target/classes");
See also KeycloakContainerExtensionTest
class.
The release versions of this project are available at Maven Central.
Simply put the dependency coordinates to your pom.xml
(or something similar, if you use e.g. Gradle or something else):
<dependency>
<groupId>com.github.dasniko</groupId>
<artifactId>testcontainers-keycloak</artifactId>
<version>VERSION</version>
<scope>test</scope>
</dependency>
This info is not specific to the Keycloak Testcontainer, but using Testcontainers generally.
I mention it here, as I see people asking again and again on how to use it in their test setup, when they think they need to specify a fixed port in their properties or YAML files...
You don't have to!
But you have to read the Testcontainers docs and the docs of your application framework on testing resources!!
Dynamic context configuration with context initializers is your friend.
In particular, look for @ContextConfiguration
and ApplicationContextInitializer<ConfigurableApplicationContext>
:
- https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#spring-testing-annotation-contextconfiguration
- https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#testcontext-ctx-management-initializers
Read the docs about the Quarkus Test Resources and use @QuarkusTestResource
with QuarkusTestResourceLifecycleManager
Consult the docs of your application framework testing capabilities on how to dynamically configure your stack for testing!
Testcontainers-Keycloak | Testcontainers | Keycloak |
---|---|---|
1.2.0 | 1.12.3 | 8.0.1 |
1.3.0 | 1.12.3 | 8.0.1 |
1.3.1 | 1.13.0 | 9.0.2 |
1.3.3 | 1.13.0 | 10.0.2 |
1.4.0 | 1.13.0 | 11.0.2 |
1.5.0 | 1.15.1 | 12.0.1 |
1.6.0 | 1.15.1 | 12.0.1 |
1.6.1 | 1.15.1 | 12.0.4 |
1.7.0 | 1.15.3 | 13.0.0 |
1.7.1 | 1.15.3 | 13.0.1 |
1.8.0 | 1.15.3 | 15.0.2 |
1.9.0 | 1.16.2 | 16.0.0 |
There might also be other possible version configurations which will work.
See also the Releases page for version and feature update notes.
Many thanks to the creators and maintainers of Testcontainers. You do an awesome job!
Same goes to the whole Keycloak team!
Kudos to @thomasdarimont for some inspiration for this project.
MIT License
Copyright (c) 2019-2021 Niko Köbler
See LICENSE file for details.