[KEYCLOAK-11784] - Quarkus Extension

Co-authored-by: stianst <stianst@gmail.com>
This commit is contained in:
Pedro Igor 2020-05-18 19:48:13 -03:00 committed by Stian Thorgersen
parent 6f43b58ccf
commit 68024396f1
46 changed files with 961 additions and 722 deletions

View file

@ -32,7 +32,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<artifactId>keycloak-quarkus-server</artifactId> <artifactId>keycloak-quarkus-server-app</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>

View file

@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>keycloak-quarkus-parent</artifactId> <artifactId>keycloak-quarkus-parent</artifactId>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
@ -10,124 +10,93 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<name>Keycloak Quarkus Extensions</name> <name>Keycloak Quarkus Server Deployment</name>
<artifactId>keycloak-quarkus-extensions</artifactId> <artifactId>keycloak-quarkus-server-deployment</artifactId>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.jboss.resteasy</groupId> <groupId>io.quarkus</groupId>
<artifactId>resteasy-core</artifactId> <artifactId>quarkus-core-deployment</artifactId>
<exclusions> <version>${quarkus.version}</version>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
<exclusion>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_4.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_4.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi-private</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-commons</artifactId>
<version>${infinispan.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal</artifactId> <artifactId>quarkus-arc-deployment</artifactId>
<version>${quarkus.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId> <artifactId>keycloak-quarkus-server</artifactId>
<exclusions> <version>${project.version}</version>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-web</artifactId> <artifactId>quarkus-resteasy-deployment</artifactId>
<version>${quarkus.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>io.quarkus</groupId>
<artifactId>keycloak-common</artifactId> <artifactId>quarkus-resteasy-jackson-deployment</artifactId>
<exclusions> <version>${quarkus.version}</version>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.liquibase</groupId> <groupId>io.quarkus</groupId>
<artifactId>liquibase-core</artifactId> <artifactId>quarkus-hibernate-orm-deployment</artifactId>
<version>${quarkus.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>io.quarkus</groupId>
<artifactId>junit</artifactId> <artifactId>quarkus-jdbc-h2-deployment</artifactId>
<version>${quarkus.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql-deployment</artifactId>
<version>${quarkus.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-mariadb-deployment</artifactId>
<version>${quarkus.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bootstrap-core</artifactId>
<version>${quarkus.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
<version>${quarkus.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
<plugins> <plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${quarkus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId> <artifactId>maven-dependency-plugin</artifactId>
@ -145,7 +114,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.jboss.jandex</groupId> <groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId> <artifactId>jandex-maven-plugin</artifactId>
@ -194,12 +162,9 @@
</executions> </executions>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<configuration> <configuration>
<environmentVariables> <skip>true</skip>
<KEYCLOAK_CAMEL_CASE_SCOPE_CAMEL_CASE_PROP>foobar</KEYCLOAK_CAMEL_CASE_SCOPE_CAMEL_CASE_PROP>
</environmentVariables>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

View file

@ -0,0 +1,32 @@
package org.keycloak.quarkus.deployment;
import java.util.List;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
import org.keycloak.runtime.KeycloakRecorder;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.hibernate.orm.deployment.PersistenceUnitDescriptorBuildItem;
class KeycloakProcessor {
@BuildStep
FeatureBuildItem getFeature() {
return new FeatureBuildItem("keycloak");
}
@Record(ExecutionTime.STATIC_INIT)
@BuildStep
void configureHibernate(KeycloakRecorder recorder, List<PersistenceUnitDescriptorBuildItem> descriptors) {
ParsedPersistenceXmlDescriptor unit = descriptors.get(0).getDescriptor();
unit.setTransactionType(PersistenceUnitTransactionType.JTA);
unit.getProperties().setProperty(AvailableSettings.DIALECT,
KeycloakRecorder.CONFIG.getRawValue("quarkus.datasource.dialect"));
}
}

View file

@ -1,4 +1,4 @@
package org.keycloak.connections.liquibase; package org.keycloak.quarkus.deployment;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -11,8 +11,11 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import liquibase.exception.ServiceNotFoundException; import io.agroal.api.configuration.AgroalDataSourceConfiguration;
import liquibase.parser.core.xml.XMLChangeLogSAXParser; import io.quarkus.agroal.deployment.JdbcDataSourceBuildItem;
import io.quarkus.arc.deployment.BeanContainerListenerBuildItem;
import io.quarkus.datasource.runtime.DataSourceBuildTimeConfig;
import io.quarkus.datasource.runtime.DataSourcesBuildTimeConfig;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo; import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
@ -21,22 +24,28 @@ import org.jboss.jandex.IndexReader;
import org.keycloak.connections.jpa.updater.liquibase.lock.CustomInsertLockRecordGenerator; import org.keycloak.connections.jpa.updater.liquibase.lock.CustomInsertLockRecordGenerator;
import org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockDatabaseChangeLogGenerator; import org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockDatabaseChangeLogGenerator;
import org.keycloak.connections.jpa.updater.liquibase.lock.DummyLockService; import org.keycloak.connections.jpa.updater.liquibase.lock.DummyLockService;
import org.keycloak.connections.liquibase.KeycloakLogger;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import liquibase.database.Database; import liquibase.database.Database;
import liquibase.lockservice.LockService; import liquibase.lockservice.LockService;
import liquibase.logging.Logger; import liquibase.logging.Logger;
import liquibase.parser.ChangeLogParser; import liquibase.parser.ChangeLogParser;
import liquibase.servicelocator.DefaultPackageScanClassResolver; import liquibase.parser.core.xml.XMLChangeLogSAXParser;
import liquibase.servicelocator.LiquibaseService; import liquibase.servicelocator.LiquibaseService;
import liquibase.servicelocator.ServiceLocator;
import liquibase.sqlgenerator.SqlGenerator; import liquibase.sqlgenerator.SqlGenerator;
import org.keycloak.runtime.KeycloakRecorder;
public class FastServiceLocator extends ServiceLocator { class LiquibaseProcessor {
private static Map<String, List<String>> CLASS_INDEX = new HashMap<>(); @Record(ExecutionTime.STATIC_INIT)
@BuildStep
static { void configure(KeycloakRecorder recorder) {
DotName liquibaseServiceName = DotName.createSimple(LiquibaseService.class.getName()); DotName liquibaseServiceName = DotName.createSimple(LiquibaseService.class.getName());
Map<String, List<String>> services = new HashMap<>();
try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/liquibase.idx")) { try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/liquibase.idx")) {
IndexReader reader = new IndexReader(in); IndexReader reader = new IndexReader(in);
@ -54,7 +63,7 @@ public class FastServiceLocator extends ServiceLocator {
LockService.class, LockService.class,
SqlGenerator.class)) { SqlGenerator.class)) {
List<String> impls = new ArrayList<>(); List<String> impls = new ArrayList<>();
CLASS_INDEX.put(c.getName(), impls); services.put(c.getName(), impls);
Set<ClassInfo> classes = new HashSet<>(); Set<ClassInfo> classes = new HashSet<>();
if (c.isInterface()) { if (c.isInterface()) {
classes.addAll(index.getAllKnownImplementors(DotName.createSimple(c.getName()))); classes.addAll(index.getAllKnownImplementors(DotName.createSimple(c.getName())));
@ -78,68 +87,12 @@ public class FastServiceLocator extends ServiceLocator {
throw new RuntimeException("Failed to get liquibase jandex index", cause); throw new RuntimeException("Failed to get liquibase jandex index", cause);
} }
CLASS_INDEX.put(Logger.class.getName(), Arrays.asList(KeycloakLogger.class.getName())); services.put(Logger.class.getName(), Arrays.asList(KeycloakLogger.class.getName()));
CLASS_INDEX.put(LockService.class.getName(), Arrays.asList(DummyLockService.class.getName())); services.put(LockService.class.getName(), Arrays.asList(DummyLockService.class.getName()));
CLASS_INDEX.put(ChangeLogParser.class.getName(), Arrays.asList(XMLChangeLogSAXParser.class.getName())); services.put(ChangeLogParser.class.getName(), Arrays.asList(XMLChangeLogSAXParser.class.getName()));
CLASS_INDEX.get(SqlGenerator.class.getName()).add(CustomInsertLockRecordGenerator.class.getName()); services.get(SqlGenerator.class.getName()).add(CustomInsertLockRecordGenerator.class.getName());
CLASS_INDEX.get(SqlGenerator.class.getName()).add(CustomLockDatabaseChangeLogGenerator.class.getName()); services.get(SqlGenerator.class.getName()).add(CustomLockDatabaseChangeLogGenerator.class.getName());
}
protected FastServiceLocator() { recorder.configureLiquibase(services);
super(new DefaultPackageScanClassResolver() {
@Override
public Set<Class<?>> findImplementations(Class parent, String... packageNames) {
List<String> found = CLASS_INDEX.get(parent.getName());
if (found == null) {
return super.findImplementations(parent, packageNames);
}
Set<Class<?>> ret = new HashSet<>();
for (String i : found) {
try {
ret.add(Class.forName(i, false, Thread.currentThread().getContextClassLoader()));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return ret;
}
});
if (!System.getProperties().containsKey("liquibase.scan.packages")) {
if (getPackages().remove("liquibase.core")) {
addPackageToScan("liquibase.core.xml");
}
if (getPackages().remove("liquibase.parser")) {
addPackageToScan("liquibase.parser.core.xml");
}
if (getPackages().remove("liquibase.serializer")) {
addPackageToScan("liquibase.serializer.core.xml");
}
getPackages().remove("liquibase.ext");
getPackages().remove("liquibase.sdk");
}
// we only need XML parsers
getPackages().remove("liquibase.parser.core.yaml");
getPackages().remove("liquibase.serializer.core.yaml");
getPackages().remove("liquibase.parser.core.json");
getPackages().remove("liquibase.serializer.core.json");
}
@Override
public Object newInstance(Class requiredInterface) throws ServiceNotFoundException {
if (Logger.class.equals(requiredInterface)) {
return new KeycloakLogger();
}
return super.newInstance(requiredInterface);
}
public void register(Class<? extends Database> type) {
CLASS_INDEX.put(Database.class.getName(), Arrays.asList(type.getName()));
} }
} }

View file

@ -0,0 +1,28 @@
package test.org.keycloak.quarkus;
import org.hamcrest.Matchers;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
public class TestStartup {
@RegisterExtension
static final QuarkusUnitTest test = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addAsResource("application.properties", "application.properties")
.addAsResource("keycloak.properties", "META-INF/keycloak.properties"));
@Test
public void testWelcomePage() throws InterruptedException {
RestAssured.given()
.when().get("/")
.then()
.statusCode(200)
.body(Matchers.containsString("Please create an initial admin user to get started"));
}
}

View file

@ -0,0 +1,4 @@
quarkus.log.level = INFO
quarkus.application.name=Keycloak
resteasy.disable.html.sanitizer = true

View file

@ -0,0 +1,9 @@
hostname.default.frontendUrl = ${keycloak.frontendUrl:}
# Datasource
datasource.dialect=org.hibernate.dialect.H2Dialect
datasource.jdbc.transactions=xa
datasource.driver=org.h2.jdbcx.JdbcDataSource
datasource.url = jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
datasource.username = sa
datasource.password = keycloak

View file

@ -36,6 +36,7 @@
<jackson.version>2.10.2</jackson.version> <jackson.version>2.10.2</jackson.version>
<jackson.databind.version>${jackson.version}</jackson.databind.version> <jackson.databind.version>${jackson.version}</jackson.databind.version>
<hibernate.version>5.4.14.Final</hibernate.version> <hibernate.version>5.4.14.Final</hibernate.version>
<snakeyaml.version>1.20</snakeyaml.version>
<surefire-plugin.version>2.22.0</surefire-plugin.version> <surefire-plugin.version>2.22.0</surefire-plugin.version>
@ -50,16 +51,36 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId> <artifactId>quarkus-bom-deployment</artifactId>
<version>${quarkus.version}</version> <version>${quarkus.version}</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<artifactId>keycloak-quarkus-extensions</artifactId> <artifactId>keycloak-quarkus-server</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-commons</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-client-hotrod</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.wildfly.common</groupId> <groupId>org.wildfly.common</groupId>
<artifactId>wildfly-common</artifactId> <artifactId>wildfly-common</artifactId>
@ -74,13 +95,41 @@
<dependency> <dependency>
<groupId>org.yaml</groupId> <groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId> <artifactId>snakeyaml</artifactId>
<version>1.20</version> <version>${snakeyaml.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-commons</artifactId>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.0.8</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<modules> <modules>
<module>extensions</module> <module>deployment</module>
<module>runtime</module>
<module>server</module> <module>server</module>
</modules> </modules>

475
quarkus/runtime/pom.xml Normal file
View file

@ -0,0 +1,475 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<parent>
<artifactId>keycloak-quarkus-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>11.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>Keycloak Quarkus Server Extension</name>
<artifactId>keycloak-quarkus-server</artifactId>
<dependencies>
<!-- Quarkus -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-mariadb</artifactId>
</dependency>
<!-- Keycloak -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-js-adapter</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi-private</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-themes</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core-public</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-infinispan</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-policy-common</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-kerberos-federation</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-sssd-federation</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-ldap-federation</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Keycloak Dependencies-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>commons-logging-jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>com.webauthn4j</groupId>
<artifactId>webauthn4j-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.webauthn4j</groupId>
<artifactId>webauthn4j-util</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-client-hotrod</artifactId>
<version>${infinispan.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-cachestore-remote</artifactId>
<version>${infinispan.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.ua-parser</groupId>
<artifactId>uap-java</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>${jakarta.mail.version}</version>
</dependency>
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>${xmlsec.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-core</artifactId>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
<exclusion>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_4.0_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-web</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bootstrap-maven-plugin</artifactId>
<version>${quarkus.version}</version>
<executions>
<execution>
<goals>
<goal>extension-descriptor</goal>
</goals>
<phase>compile</phase>
<configuration>
<deployment>${project.groupId}:${project.artifactId}-deployment:${project.version}
</deployment>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${quarkus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<environmentVariables>
<KEYCLOAK_CAMEL_CASE_SCOPE_CAMEL_CASE_PROP>foobar</KEYCLOAK_CAMEL_CASE_SCOPE_CAMEL_CASE_PROP>
</environmentVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -19,6 +19,21 @@ package org.keycloak.connections.jpa;
import static org.keycloak.connections.liquibase.QuarkusJpaUpdaterProvider.VERIFY_AND_RUN_MASTER_CHANGELOG; import static org.keycloak.connections.liquibase.QuarkusJpaUpdaterProvider.VERIFY_AND_RUN_MASTER_CHANGELOG;
import java.io.File;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.CDI;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.SynchronizationType;
import org.hibernate.internal.SessionFactoryImpl; import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.internal.SessionImpl; import org.hibernate.internal.SessionImpl;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -35,20 +50,6 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.provider.ServerInfoAwareProviderFactory; import org.keycloak.provider.ServerInfoAwareProviderFactory;
import org.keycloak.transaction.JtaTransactionManagerLookup; import org.keycloak.transaction.JtaTransactionManagerLookup;
import javax.enterprise.inject.Instance;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.SynchronizationType;
import java.io.File;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.enterprise.inject.spi.CDI;
/** /**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a> * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/ */

View file

@ -0,0 +1,99 @@
package org.keycloak.connections.liquibase;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import liquibase.database.DatabaseFactory;
import liquibase.exception.ServiceNotFoundException;
import liquibase.database.Database;
import liquibase.logging.Logger;
import liquibase.servicelocator.DefaultPackageScanClassResolver;
import liquibase.servicelocator.ServiceLocator;
public class FastServiceLocator extends ServiceLocator {
private final Map<String, List<String>> services;
public FastServiceLocator(Map<String, List<String>> services) {
super(new DefaultPackageScanClassResolver() {
@Override
public Set<Class<?>> findImplementations(Class parent, String... packageNames) {
List<String> found = services.get(parent.getName());
if (found == null) {
return super.findImplementations(parent, packageNames);
}
Set<Class<?>> ret = new HashSet<>();
for (String i : found) {
try {
ret.add(Class.forName(i, false, Thread.currentThread().getContextClassLoader()));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return ret;
}
});
if (!System.getProperties().containsKey("liquibase.scan.packages")) {
if (getPackages().remove("liquibase.core")) {
addPackageToScan("liquibase.core.xml");
}
if (getPackages().remove("liquibase.parser")) {
addPackageToScan("liquibase.parser.core.xml");
}
if (getPackages().remove("liquibase.serializer")) {
addPackageToScan("liquibase.serializer.core.xml");
}
getPackages().remove("liquibase.ext");
getPackages().remove("liquibase.sdk");
}
// we only need XML parsers
getPackages().remove("liquibase.parser.core.yaml");
getPackages().remove("liquibase.serializer.core.yaml");
getPackages().remove("liquibase.parser.core.json");
getPackages().remove("liquibase.serializer.core.json");
this.services = services;
}
@Override
public Object newInstance(Class requiredInterface) throws ServiceNotFoundException {
if (Logger.class.equals(requiredInterface)) {
return new KeycloakLogger();
}
return super.newInstance(requiredInterface);
}
@Override
public <T> Class<? extends T>[] findClasses(Class<T> requiredInterface) throws ServiceNotFoundException {
List<String> found = services.get(requiredInterface.getName());
if (found == null) {
return super.findClasses(requiredInterface);
}
Set<Class<?>> ret = new HashSet<>();
for (String i : found) {
try {
ret.add(Class.forName(i, false, Thread.currentThread().getContextClassLoader()));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return ret.toArray(new Class[ret.size()]);
}
public void register(Database database) {
DatabaseFactory.getInstance().register(database);
}
}

View file

@ -48,7 +48,11 @@ public class QuarkusJpaUpdaterProviderFactory implements JpaUpdaterProviderFacto
@Override @Override
public String getId() { public String getId() {
return "liquibase"; return "quarkus";
} }
@Override
public int order() {
return 100;
}
} }

View file

@ -73,23 +73,8 @@ public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionPr
} }
protected void baseLiquibaseInitialization(KeycloakSession session) { protected void baseLiquibaseInitialization(KeycloakSession session) {
LogFactory.setInstance(new LogFactory() {
KeycloakLogger logger = new KeycloakLogger();
@Override
public liquibase.logging.Logger getLog(String name) {
return logger;
}
@Override
public liquibase.logging.Logger getLog() {
return logger;
}
});
resourceAccessor = new ClassLoaderResourceAccessor(getClass().getClassLoader()); resourceAccessor = new ClassLoaderResourceAccessor(getClass().getClassLoader());
FastServiceLocator locator = new FastServiceLocator(); FastServiceLocator locator = (FastServiceLocator) ServiceLocator.getInstance();
ServiceLocator.setInstance(locator);
JpaConnectionProviderFactory jpaConnectionProvider = (JpaConnectionProviderFactory) session JpaConnectionProviderFactory jpaConnectionProvider = (JpaConnectionProviderFactory) session
.getKeycloakSessionFactory().getProviderFactory(JpaConnectionProvider.class); .getKeycloakSessionFactory().getProviderFactory(JpaConnectionProvider.class);
@ -101,22 +86,20 @@ public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionPr
DatabaseFactory.getInstance().clearRegistry(); DatabaseFactory.getInstance().clearRegistry();
if (database.getDatabaseProductName().equals(PostgresDatabase.PRODUCT_NAME)) { if (database.getDatabaseProductName().equals(PostgresDatabase.PRODUCT_NAME)) {
// Adding PostgresPlus support to liquibase // Adding PostgresPlus support to liquibase
DatabaseFactory.getInstance().register(new PostgresPlusDatabase()); locator.register(new PostgresPlusDatabase());
} else if (database.getDatabaseProductName().equals(MySQLDatabase.PRODUCT_NAME)) { } else if (database.getDatabaseProductName().equals(MySQLDatabase.PRODUCT_NAME)) {
// Adding newer version of MySQL/MariaDB support to liquibase // Adding newer version of MySQL/MariaDB support to liquibase
DatabaseFactory.getInstance().register(new UpdatedMySqlDatabase()); locator.register(new UpdatedMySqlDatabase());
// Adding CustomVarcharType for MySQL 8 and newer // Adding CustomVarcharType for MySQL 8 and newer
DataTypeFactory.getInstance().register(MySQL8VarcharType.class); DataTypeFactory.getInstance().register(MySQL8VarcharType.class);
} else if (database.getDatabaseProductName().equals(MariaDBDatabase.PRODUCT_NAME)) { } else if (database.getDatabaseProductName().equals(MariaDBDatabase.PRODUCT_NAME)) {
DatabaseFactory.getInstance().register(new UpdatedMariaDBDatabase()); locator.register(new UpdatedMariaDBDatabase());
// Adding CustomVarcharType for MySQL 8 and newer // Adding CustomVarcharType for MySQL 8 and newer
DataTypeFactory.getInstance().register(MySQL8VarcharType.class); DataTypeFactory.getInstance().register(MySQL8VarcharType.class);
} else { } else {
DatabaseFactory.getInstance().register(database); locator.register(database);
} }
locator.register(database.getClass());
// disables XML validation // disables XML validation
for (ChangeLogParser parser : ChangeLogParserFactory.getInstance().getParsers()) { for (ChangeLogParser parser : ChangeLogParserFactory.getInstance().getParsers()) {
if (parser instanceof XMLChangeLogSAXParser) { if (parser instanceof XMLChangeLogSAXParser) {
@ -126,6 +109,7 @@ public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionPr
getSaxParserFactory.setAccessible(true); getSaxParserFactory.setAccessible(true);
SAXParserFactory saxParserFactory = (SAXParserFactory) getSaxParserFactory.invoke(parser); SAXParserFactory saxParserFactory = (SAXParserFactory) getSaxParserFactory.invoke(parser);
saxParserFactory.setValidating(false); saxParserFactory.setValidating(false);
saxParserFactory.setSchema(null);
} catch (Exception e) { } catch (Exception e) {
logger.warnf("Failed to disable liquibase XML validations"); logger.warnf("Failed to disable liquibase XML validations");
} finally { } finally {
@ -155,7 +139,7 @@ public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionPr
@Override @Override
public String getId() { public String getId() {
return "default"; return "quarkus";
} }
@Override @Override
@ -168,7 +152,7 @@ public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionPr
String changelog = QuarkusJpaUpdaterProvider.CHANGELOG; String changelog = QuarkusJpaUpdaterProvider.CHANGELOG;
logger.debugf("Using changelog file %s and changelogTableName %s", changelog, database.getDatabaseChangeLogTableName()); logger.debugf("Using changelog file %s and changelogTableName %s", changelog, database.getDatabaseChangeLogTableName());
return new Liquibase(changelog, resourceAccessor, database); return new Liquibase(changelog, resourceAccessor, database);
} }
@ -186,4 +170,9 @@ public class QuarkusLiquibaseConnectionProvider implements LiquibaseConnectionPr
return new Liquibase(changelogLocation, resourceAccessor, database); return new Liquibase(changelogLocation, resourceAccessor, database);
} }
@Override
public int order() {
return 100;
}
} }

View file

@ -0,0 +1,40 @@
package org.keycloak.runtime;
import java.util.List;
import java.util.Map;
import org.keycloak.connections.liquibase.FastServiceLocator;
import org.keycloak.connections.liquibase.KeycloakLogger;
import io.quarkus.runtime.annotations.Recorder;
import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.SmallRyeConfigProviderResolver;
import liquibase.logging.LogFactory;
import liquibase.servicelocator.ServiceLocator;
@Recorder
public class KeycloakRecorder {
public static final SmallRyeConfig CONFIG;
static {
CONFIG = (SmallRyeConfig) SmallRyeConfigProviderResolver.instance().getConfig();
}
public void configureLiquibase(Map<String, List<String>> services) {
LogFactory.setInstance(new LogFactory() {
KeycloakLogger logger = new KeycloakLogger();
@Override
public liquibase.logging.Logger getLog(String name) {
return logger;
}
@Override
public liquibase.logging.Logger getLog() {
return logger;
}
});
ServiceLocator.setInstance(new FastServiceLocator(services));
}
}

View file

@ -0,0 +1,9 @@
---
name: "Keycloak"
metadata:
keywords:
- "keycloak"
guide: "https://keycloak.org"
categories:
- "security"
status: "preview"

View file

@ -2,429 +2,59 @@
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent> <parent>
<artifactId>keycloak-quarkus-parent</artifactId> <artifactId>keycloak-quarkus-parent</artifactId>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<version>11.0.0-SNAPSHOT</version> <version>11.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion>
<name>Keycloak Quarkus Server App</name>
<artifactId>keycloak-quarkus-server-app</artifactId>
<name>Keycloak Quarkus Server</name> <properties>
<artifactId>keycloak-quarkus-server</artifactId> <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus</quarkus.platform.group-id>
<surefire-plugin.version>2.22.1</surefire-plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<!-- Quarkus -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal</artifactId>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-mariadb</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<!-- Keycloak -->
<dependency> <dependency>
<groupId>org.keycloak</groupId> <groupId>org.keycloak</groupId>
<artifactId>keycloak-quarkus-extensions</artifactId> <artifactId>keycloak-quarkus-server</artifactId>
</dependency> <version>${project.version}</version>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-js-adapter</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi-private</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-themes</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core-public</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-infinispan</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-policy-common</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-kerberos-federation</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-sssd-federation</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-ldap-federation</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Keycloak Dependencies-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>commons-logging-jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>com.webauthn4j</groupId>
<artifactId>webauthn4j-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.webauthn4j</groupId>
<artifactId>webauthn4j-util</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-commons</artifactId>
<version>${infinispan.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-client-hotrod</artifactId>
<version>${infinispan.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-cachestore-remote</artifactId>
<version>${infinispan.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.ua-parser</groupId>
<artifactId>uap-java</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>${jakarta.mail.version}</version>
</dependency>
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>${xmlsec.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<finalName>keycloak</finalName> <finalName>keycloak</finalName>
<plugins> <plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>io.quarkus</groupId> <groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId> <artifactId>quarkus-maven-plugin</artifactId>
@ -443,5 +73,50 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.version}</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<configuration>
<enableHttpUrlHandler>true</enableHttpUrlHandler>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project> </project>

View file

@ -1,9 +1,9 @@
hostname.default.frontendUrl = ${keycloak.frontendUrl:} hostname.default.frontendUrl = ${keycloak.frontendUrl:}
# Datasource # Datasource
datasource.dialect=org.hibernate.dialect.H2Dialect
datasource.driver=org.h2.jdbcx.JdbcDataSource datasource.driver=org.h2.jdbcx.JdbcDataSource
datasource.url = jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 datasource.url = jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
#datasource.url = jdbc:h2:file:/tmp/keycloak-server-quarkus
datasource.username = sa datasource.username = sa
datasource.password = keycloak datasource.password = keycloak
datasource.jdbc.transactions=xa datasource.jdbc.transactions=xa

View file

@ -1,93 +0,0 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="keycloak-default" transaction-type="JTA">
<class>org.keycloak.models.jpa.entities.ClientEntity</class>
<class>org.keycloak.models.jpa.entities.ClientAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
<class>org.keycloak.models.jpa.entities.RealmAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
<class>org.keycloak.models.jpa.entities.ComponentConfigEntity</class>
<class>org.keycloak.models.jpa.entities.ComponentEntity</class>
<class>org.keycloak.models.jpa.entities.UserFederationProviderEntity</class>
<class>org.keycloak.models.jpa.entities.UserFederationMapperEntity</class>
<class>org.keycloak.models.jpa.entities.RoleEntity</class>
<class>org.keycloak.models.jpa.entities.RoleAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.FederatedIdentityEntity</class>
<class>org.keycloak.models.jpa.entities.MigrationModelEntity</class>
<class>org.keycloak.models.jpa.entities.UserEntity</class>
<class>org.keycloak.models.jpa.entities.UserRequiredActionEntity</class>
<class>org.keycloak.models.jpa.entities.UserAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
<class>org.keycloak.models.jpa.entities.IdentityProviderEntity</class>
<class>org.keycloak.models.jpa.entities.IdentityProviderMapperEntity</class>
<class>org.keycloak.models.jpa.entities.ProtocolMapperEntity</class>
<class>org.keycloak.models.jpa.entities.UserConsentEntity</class>
<class>org.keycloak.models.jpa.entities.UserConsentClientScopeEntity</class>
<class>org.keycloak.models.jpa.entities.AuthenticationFlowEntity</class>
<class>org.keycloak.models.jpa.entities.AuthenticationExecutionEntity</class>
<class>org.keycloak.models.jpa.entities.AuthenticatorConfigEntity</class>
<class>org.keycloak.models.jpa.entities.RequiredActionProviderEntity</class>
<class>org.keycloak.models.jpa.session.PersistentUserSessionEntity</class>
<class>org.keycloak.models.jpa.session.PersistentClientSessionEntity</class>
<class>org.keycloak.models.jpa.entities.GroupEntity</class>
<class>org.keycloak.models.jpa.entities.GroupAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.GroupRoleMappingEntity</class>
<class>org.keycloak.models.jpa.entities.UserGroupMembershipEntity</class>
<class>org.keycloak.models.jpa.entities.ClientScopeEntity</class>
<class>org.keycloak.models.jpa.entities.ClientScopeAttributeEntity</class>
<class>org.keycloak.models.jpa.entities.ClientScopeRoleMappingEntity</class>
<class>org.keycloak.models.jpa.entities.ClientScopeClientMappingEntity</class>
<class>org.keycloak.models.jpa.entities.DefaultClientScopeRealmMappingEntity</class>
<class>org.keycloak.models.jpa.entities.ClientInitialAccessEntity</class>
<!-- JpaAuditProviders -->
<class>org.keycloak.events.jpa.EventEntity</class>
<class>org.keycloak.events.jpa.AdminEventEntity</class>
<!-- Authorization -->
<class>org.keycloak.authorization.jpa.entities.ResourceServerEntity</class>
<class>org.keycloak.authorization.jpa.entities.ResourceEntity</class>
<class>org.keycloak.authorization.jpa.entities.ScopeEntity</class>
<class>org.keycloak.authorization.jpa.entities.PolicyEntity</class>
<class>org.keycloak.authorization.jpa.entities.PermissionTicketEntity</class>
<class>org.keycloak.authorization.jpa.entities.ResourceAttributeEntity</class>
<!-- User Federation Storage -->
<class>org.keycloak.storage.jpa.entity.BrokerLinkEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUser</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserAttributeEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserConsentEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserConsentClientScopeEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserCredentialEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserGroupMembershipEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserRequiredActionEntity</class>
<class>org.keycloak.storage.jpa.entity.FederatedUserRoleMappingEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.query.startup_check" value="false"/>
</properties>
</persistence-unit>
</persistence>

View file

@ -1,4 +1,4 @@
#quarkus.log.level = DEBUG #quarkus.log.level = DEBUG
quarkus.http.root-path=/auth
quarkus.application.name=Keycloak quarkus.application.name=Keycloak
resteasy.disable.html.sanitizer = true resteasy.disable.html.sanitizer = true