From 6b75adb50016f614f7c1c5c8b7a0c0784884e5d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niko=20Ko=CC=88bler?= Date: Mon, 26 Feb 2024 20:02:05 +0100 Subject: [PATCH] initializer demo to set fixed issuer --- initializer/pom.xml | 45 +++++++++++ .../issuer/IssuerInitializerProvider.java | 78 +++++++++++++++++++ .../initializer/InitiailizerTest.java | 47 +++++++++++ pom.xml | 12 +++ 4 files changed, 182 insertions(+) create mode 100644 initializer/src/main/java/dasniko/keycloak/initializer/issuer/IssuerInitializerProvider.java create mode 100644 initializer/src/test/java/dasniko/keycloak/initializer/InitiailizerTest.java diff --git a/initializer/pom.xml b/initializer/pom.xml index 6e448b1..1683d04 100644 --- a/initializer/pom.xml +++ b/initializer/pom.xml @@ -42,11 +42,56 @@ org.slf4j slf4j-api + + net.bytebuddy + byte-buddy + + + net.bytebuddy + byte-buddy-agent + com.cronutils cron-utils 9.2.1 + + + dasniko.keycloak + keycloak-utils + ${project.version} + test + + + org.junit.jupiter + junit-jupiter + + + org.junit.jupiter + junit-jupiter-params + + + org.testcontainers + junit-jupiter + + + com.github.dasniko + testcontainers-keycloak + + + io.rest-assured + rest-assured + + + org.slf4j + slf4j-log4j12 + + + org.jboss.shrinkwrap.resolver + shrinkwrap-resolver-impl-maven-archive + 3.3.0 + test + diff --git a/initializer/src/main/java/dasniko/keycloak/initializer/issuer/IssuerInitializerProvider.java b/initializer/src/main/java/dasniko/keycloak/initializer/issuer/IssuerInitializerProvider.java new file mode 100644 index 0000000..9bc914b --- /dev/null +++ b/initializer/src/main/java/dasniko/keycloak/initializer/issuer/IssuerInitializerProvider.java @@ -0,0 +1,78 @@ +package dasniko.keycloak.initializer.issuer; + +import com.google.auto.service.AutoService; +import dasniko.keycloak.initializer.InitializerProviderFactory; +import lombok.extern.slf4j.Slf4j; +import net.bytebuddy.ByteBuddy; +import net.bytebuddy.agent.ByteBuddyAgent; +import net.bytebuddy.dynamic.loading.ClassReloadingStrategy; +import net.bytebuddy.implementation.MethodDelegation; +import org.keycloak.Config; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.provider.ProviderConfigurationBuilder; +import org.keycloak.services.Urls; +import org.keycloak.services.validation.Validation; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.returns; + +@Slf4j +@AutoService(InitializerProviderFactory.class) +public class IssuerInitializerProvider implements InitializerProviderFactory { + + public static final String PROVIDER_ID = "issuer"; + + private static final String CONFIG_ATTR_BASE_URI = "base-uri"; + + private static String issuerBaseUri; + + @Override + public String getId() { + return PROVIDER_ID; + } + + @Override + public void init(Config.Scope config) { + issuerBaseUri = config.get(CONFIG_ATTR_BASE_URI); + if (!Validation.isBlank(issuerBaseUri)) { + log.info("Issuer BaseURI fixed value: {}", issuerBaseUri); + } + } + + @Override + public void postInit(KeycloakSessionFactory factory) { + ByteBuddyAgent.install(); + new ByteBuddy() + .redefine(Urls.class) + .method(named("realmIssuer").and(isDeclaredBy(Urls.class).and(returns(String.class)))) + .intercept(MethodDelegation.to(this.getClass())) + .make() + .load(Urls.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent()); + } + + @SuppressWarnings("unused") + public static String realmIssuer(URI baseUri, String realmName) { + try { + baseUri = new URI(issuerBaseUri); + } catch (URISyntaxException | NullPointerException ignored) { + } + return Urls.realmBase(baseUri).path("{realm}").build(realmName).toString(); + } + + @Override + public List getConfigMetadata() { + return ProviderConfigurationBuilder.create() + .property() + .name(CONFIG_ATTR_BASE_URI) + .type(ProviderConfigProperty.STRING_TYPE) + .helpText("The baseUri to use for the issuer of this server. Keep empty, if the regular hostname settings should be used.") + .add() + .build(); + } +} diff --git a/initializer/src/test/java/dasniko/keycloak/initializer/InitiailizerTest.java b/initializer/src/test/java/dasniko/keycloak/initializer/InitiailizerTest.java new file mode 100644 index 0000000..459b5c5 --- /dev/null +++ b/initializer/src/test/java/dasniko/keycloak/initializer/InitiailizerTest.java @@ -0,0 +1,47 @@ +package dasniko.keycloak.initializer; + +import dasniko.testcontainers.keycloak.KeycloakContainer; +import de.keycloak.test.TestBase; +import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.io.File; +import java.util.List; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.startsWith; + +@Testcontainers +public class InitiailizerTest extends TestBase { + + public static final String ISSUER = "https://auth.keycloak.de"; + + private static final List dependencies = Maven.resolver() + .loadPomFromFile("./pom.xml") + .resolve("net.bytebuddy:byte-buddy-agent") + .withoutTransitivity().asList(File.class); + + @ParameterizedTest + @ValueSource(strings = { ISSUER, "" }) + public void testIssuer(String issuerValue) { + final KeycloakContainer keycloak = new KeycloakContainer() + .withProviderClassesFrom("target/classes") + .withProviderLibsFrom(dependencies) + .withEnv("KC_SPI_INITIALIZER_ISSUER_BASE_URI", issuerValue) +// .withDebugFixedPort(8787, true) + ; + keycloak.start(); + + String issuer = getOpenIDConfiguration(keycloak, "master").extract().path("issuer"); + if (issuerValue.isEmpty()) { + assertThat(issuer, startsWith(keycloak.getAuthServerUrl())); + } else { + assertThat(issuer, startsWith(issuerValue)); + } + + keycloak.stop(); + } + +} diff --git a/pom.xml b/pom.xml index 84c1595..506815f 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,7 @@ UTF-8 2.17.209 + 1.14.7 23.0.0 3.11.0 17 @@ -77,6 +78,17 @@ + + net.bytebuddy + byte-buddy + ${bytebuddy.version} + provided + + + net.bytebuddy + byte-buddy-agent + ${bytebuddy.version} +