Git Product home page Git Product logo

keycloak-kafka's Introduction

Keycloak Kafka Module

Simple module for Keycloak to produce keycloak events to Kafka.

Tested with

Kafka version: 2.12-2.1.x, 2.12-2.4.x, 2.12-2.5.x, 2.13-2.8, 2.13-3.3.x

Keycloak version: 19.0.x, 21.0.x

Java version: 17

Check out this older version to run the module on a Wildfly server

Build

You can simply use Maven to build the jar file. Thanks to the assembly plugin the build process will create a fat jar that includes all dependencies and makes the deployment quite easy. Just use the following command to build the jar file.

mvn clean package

Installation

First you need to build or download the keycloak-kafka module.

To install the module to your keycloak server you have to configure the module and deploy it. If you deploy the module without configuration, your keycloak server will fail to start throwing a NullPointerException.

If you want to install the module manually as described in the initial version you can follow this guide.

Module Configuration

The following properties can be set via environment variables (e.g. ${KAFKA_TOPIC}) or as parameters when starting keycloak (e.g. --spi-events-listener-kafka-topic-events).

  • topicEvents (env KAFKA_TOPIC): The name of the kafka topic to where the events will be produced to.

  • clientId (env KAFKA_CLIENT_ID): The client.id used to identify the client in kafka.

  • bootstrapServers (env KAFKA_BOOTSTRAP_SERVERS): A comma separated list of available brokers.

  • events (env KAFKA_EVENTS): The events that will be send to kafka.

  • topicAdminEvents (env KAFKA_ADMIN_TOPIC): (Optional) The name of the kafka topic to where the admin events will be produced to. No events will be produced when this property isn't set.

A list of available events can be found here

Kafka client configuration

It's also possible to configure the kafka client with environment variables or by adding parameters to the keycloak start command. This makes it possible to connect this module to a kafka broker that requires SSL/TLS connections. For example to change the timeout of how long the producer will block the thread to 10 seconds you just have to pass the following parameter to the start command.

./kc.sh start --spi-events-listener-kafka-max-block-ms 10000

Or set the following environnment variable.

KAFKA_MAX_BLOCK_MS=10000

A full list of available configurations can be found in the official kafka docs.

Kafka client using secure connection

As mentioned above the kafka client can be configured by passing parameters to the start command. To make kafka open a SSL/TLS secured connection you can add the following parameters:

./kc.sh start \
  --spi-events-listener-kafka-security-protocol SSL \
  --spi-events-listener-kafka-ssl-truststore-location kafka.client.truststore.jks \
  --spi-events-listener-kafka-ssl-truststore-password test1234

Module Deployment

Copy the keycloak-kafka-<version>-jar-with-dependencies.jar into the $KEYCLOAK_HOME/providers folder. Keycloak will automatically install the module with all it's dependencies on start up.

Keycloak Configuration

Enable Events in keycloak

  1. Open administration console
  2. Choose realm
  3. Go to Events
  4. Open Config tab and add kafka to Event Listeners.

Admin console config

Docker Container

The simplest way to enable the kafka module in a docker container is to create a custom docker image from the keycloak base image. A simple example can be found in the Dockerfile. When you build this image on your local machine by using docker build . -t keycloak-kafka, you can test everything by running the docker-compose file on your local machine. This just provides a simple example to show how it's working. Please consider to read this documentation and create your own Dockerfile.

Sample Client

The following snippet shows a minimal Spring Boot Kafka client to consume keycloak events. Additional properties can be added to the KeycloakEvent class.

@SpringBootApplication
@Log4j2
public class KafkaConsumerApplication {

	public static void main(String[] args) {
		SpringApplication.run(KafkaConsumerApplication.class, args);
	}

	@KafkaListener(topics = "keycloak-events", groupId = "event-consumer")
	public void handleKeycloakEvent(KeycloakEvent event) {
		log.info("Consumed event: " + event);
	}

	@KafkaListener(topics = "keycloak-admin-events", groupId = "event-consumer")
	public void handleKeycloakAdminEvent(KeycloakAdminEvent event) {
		log.info("Consumed admin event: " + event);
	}

	@Bean
	public StringJsonMessageConverter jsonConverter() {
		return new StringJsonMessageConverter();
	}
}

@Data
class KeycloakEvent {
	private String userId;
	private String type;
}

@Data
class KeycloakAdminEvent {
	private String realmId;
	private String operationType;
}

Contribution

Any kind of contributions are welcome.

keycloak-kafka's People

Contributors

alexted avatar dependabot[bot] avatar guiterguy219 avatar phamann avatar snuk87 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

keycloak-kafka's Issues

Example doesn't work

Hi, I'm running the example with your docker-compose with a little modification.

version: '3'
services:
  keycloak:
    depends_on:
      - "kafka"
    image: keycloak-kafka
    build:
      context: .
    ports:
      - "8084:8080"
    environment:
      KEYCLOAK_ADMIN: admin 
      KEYCLOAK_ADMIN_PASSWORD: admin
      KAFKA_TOPIC: keycloak-events
      KAFKA_CLIENT_ID: keycloak
      KAFKA_BOOTSTRAP_SERVERS: kafka:9094
    command: start-dev
    
  zookeeper:
    restart: always
    image: bitnami/zookeeper:latest
    ports:
      - "2181:2181"
    environment:    
      - ALLOW_ANONYMOUS_LOGIN=yes
      
  kafka:
    depends_on:
      - "zookeeper"
    image: bitnami/kafka:latest
    ports:
      - "9092:9092"
      - "9094:9094"
    environment:
      KAFKA_CFG_ADVERTISED_LISTENERS: INSIDE://:9092,OUTSIDE://kafka:9094
      KAFKA_CFG_LISTENERS: INSIDE://:9092,OUTSIDE://:9094
      KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_CFG_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_CREATE_TOPICS: "keycloak-events:1:1"
      ALLOW_PLAINTEXT_LISTENER: "yes"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

I see that the plugin starts, then I create an event, I can see it in the logs, but no messages are sent to the keycloak-events topic.

Logs:

Updating the configuration and installing your custom providers, if any. Please wait.
2024-03-20 21:02:11,833 WARN  [org.keycloak.services] (build-25) KC-SERVICES0047: kafka (com.github.snuk87.keycloak.kafka.KafkaEventListenerProviderFactory) is implementing the internal SPI eventsListener. This SPI is internal and may change without notice
2024-03-20 21:02:13,875 INFO  [io.quarkus.deployment.QuarkusAugmentor] (main) Quarkus augmentation completed in 3477ms
2024-03-20 21:02:14,453 INFO  [com.github.snuk87.keycloak.kafka.KafkaEventListenerProviderFactory] (main) Init kafka module ...
2024-03-20 21:02:14,489 INFO  [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: Base URL: <unset>, Hostname: <request>, Strict HTTPS: false, Path: <request>, Strict BackChannel: false, Admin URL: <unset>, Admin: <request>, Port: -1, Proxied: false
2024-03-20 21:02:15,024 INFO  [org.keycloak.common.crypto.CryptoIntegration] (main) Detected crypto provider: org.keycloak.crypto.def.DefaultCryptoProvider
2024-03-20 21:02:15,603 INFO  [org.infinispan.server.core.transport.EPollAvailable] (keycloak-cache-init) ISPN005028: Native Epoll transport not available, using NIO instead: java.lang.UnsatisfiedLinkError: could not load a native library: netty_transport_native_epoll_aarch_64
2024-03-20 21:02:15,612 WARN  [org.infinispan.PERSISTENCE] (keycloak-cache-init) ISPN000554: jboss-marshalling is deprecated and planned for removal
2024-03-20 21:02:15,657 WARN  [org.infinispan.CONFIG] (keycloak-cache-init) ISPN000569: Unable to persist Infinispan internal caches as no global state enabled
2024-03-20 21:02:15,684 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000556: Starting user marshaller 'org.infinispan.jboss.marshalling.core.JBossUserMarshaller'
2024-03-20 21:02:15,830 INFO  [org.infinispan.CONTAINER] (keycloak-cache-init) ISPN000128: Infinispan version: Infinispan 'Triskaidekaphobia' 13.0.9.Final
2024-03-20 21:02:16,472 INFO  [org.keycloak.quarkus.runtime.storage.legacy.liquibase.QuarkusJpaUpdaterProvider] (main) Initializing database schema. Using changelog META-INF/jpa-changelog-master.xml
2024-03-20 21:02:17,347 INFO  [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: node_363237, Site name: null
2024-03-20 21:02:17,402 INFO  [org.keycloak.services] (main) KC-SERVICES0050: Initializing master realm
2024-03-20 21:02:18,191 INFO  [io.quarkus] (main) Keycloak 19.0.3 on JVM (powered by Quarkus 2.7.6.Final) started in 4.257s. Listening on: http://0.0.0.0:8080
2024-03-20 21:02:18,191 INFO  [io.quarkus] (main) Profile dev activated. 
2024-03-20 21:02:18,191 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-mariadb, jdbc-mssql, jdbc-mysql, jdbc-oracle, jdbc-postgresql, keycloak, logging-gelf, narayana-jta, reactive-routes, resteasy, resteasy-jackson, smallrye-context-propagation, smallrye-health, smallrye-metrics, vault, vertx]
2024-03-20 21:02:18,391 INFO  [org.keycloak.services] (main) KC-SERVICES0009: Added user 'admin' to realm 'master'
2024-03-20 21:02:18,394 WARN  [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.
2024-03-20 21:02:38,106 INFO  [org.apache.kafka.clients.producer.ProducerConfig] (executor-thread-2) ProducerConfig values: 
	acks = 1
	batch.size = 16384
	bootstrap.servers = [kafka:9094]
	buffer.memory = 33554432
	client.dns.lookup = use_all_dns_ips
	client.id = keycloak
	compression.type = none
	connections.max.idle.ms = 540000
	delivery.timeout.ms = 120000
	enable.idempotence = false
	interceptor.classes = []
	internal.auto.downgrade.txn.commit = false
	key.serializer = class org.apache.kafka.common.serialization.StringSerializer
	linger.ms = 0
	max.block.ms = 60000
	max.in.flight.requests.per.connection = 5
	max.request.size = 1048576
	metadata.max.age.ms = 300000
	metadata.max.idle.ms = 300000
	metric.reporters = []
	metrics.num.samples = 2
	metrics.recording.level = INFO
	metrics.sample.window.ms = 30000
	partitioner.class = class org.apache.kafka.clients.producer.internals.DefaultPartitioner
	receive.buffer.bytes = 32768
	reconnect.backoff.max.ms = 1000
	reconnect.backoff.ms = 50
	request.timeout.ms = 30000
	retries = 2147483647
	retry.backoff.ms = 100
	sasl.client.callback.handler.class = null
	sasl.jaas.config = null
	sasl.kerberos.kinit.cmd = /usr/bin/kinit
	sasl.kerberos.min.time.before.relogin = 60000
	sasl.kerberos.service.name = null
	sasl.kerberos.ticket.renew.jitter = 0.05
	sasl.kerberos.ticket.renew.window.factor = 0.8
	sasl.login.callback.handler.class = null
	sasl.login.class = null
	sasl.login.refresh.buffer.seconds = 300
	sasl.login.refresh.min.period.seconds = 60
	sasl.login.refresh.window.factor = 0.8
	sasl.login.refresh.window.jitter = 0.05
	sasl.mechanism = GSSAPI
	security.protocol = PLAINTEXT
	security.providers = null
	send.buffer.bytes = 131072
	socket.connection.setup.timeout.max.ms = 30000
	socket.connection.setup.timeout.ms = 10000
	ssl.cipher.suites = null
	ssl.enabled.protocols = [TLSv1.2, TLSv1.3]
	ssl.endpoint.identification.algorithm = https
	ssl.engine.factory.class = null
	ssl.key.password = null
	ssl.keymanager.algorithm = SunX509
	ssl.keystore.certificate.chain = null
	ssl.keystore.key = null
	ssl.keystore.location = null
	ssl.keystore.password = null
	ssl.keystore.type = JKS
	ssl.protocol = TLSv1.3
	ssl.provider = null
	ssl.secure.random.implementation = null
	ssl.trustmanager.algorithm = PKIX
	ssl.truststore.certificates = null
	ssl.truststore.location = null
	ssl.truststore.password = null
	ssl.truststore.type = JKS
	transaction.timeout.ms = 60000
	transactional.id = null
	value.serializer = class org.apache.kafka.common.serialization.StringSerializer

2024-03-20 21:02:38,164 INFO  [org.apache.kafka.common.utils.AppInfoParser] (executor-thread-2) Kafka version: 2.8.0
2024-03-20 21:02:38,164 INFO  [org.apache.kafka.common.utils.AppInfoParser] (executor-thread-2) Kafka commitId: ebb1d6e21cc92130
2024-03-20 21:02:38,164 INFO  [org.apache.kafka.common.utils.AppInfoParser] (executor-thread-2) Kafka startTimeMs: 1710968558163
2024-03-20 21:02:38,291 INFO  [org.apache.kafka.clients.Metadata] (kafka-producer-network-thread | keycloak) [Producer clientId=keycloak] Cluster ID: f3GGvqwZR8SI2MrfknsFig
2024-03-20 21:10:14,344 WARN  [org.keycloak.events] (executor-thread-11) type=LOGIN_ERROR, realmId=b2f16f67-0b44-4b8f-a119-2f7dfb4208f1, clientId=null, userId=null, ipAddress=192.168.65.1, error=invalid_request
2024-03-20 21:16:08,038 WARN  [org.keycloak.events] (executor-thread-28) type=LOGIN_ERROR, realmId=b2f16f67-0b44-4b8f-a119-2f7dfb4208f1, clientId=security-admin-console, userId=null, ipAddress=192.168.65.1, error=user_not_found, auth_method=openid-connect, auth_type=code, redirect_uri=http://localhost:8084/admin/master/console/#/master/events, code_id=568c7dc2-8801-400b-a44e-addf82e77498, username=sf, authSessionParentId=568c7dc2-8801-400b-a44e-addf82e77498, authSessionTabId=MO_vSyYhWjg

Event:

2024-03-20 21:16:08,038 WARN  [org.keycloak.events] (executor-thread-28) type=LOGIN_ERROR, realmId=b2f16f67-0b44-4b8f-a119-2f7dfb4208f1, clientId=security-admin-console, userId=null, ipAddress=192.168.65.1, error=user_not_found, auth_method=openid-connect, auth_type=code, redirect_uri=http://localhost:8084/admin/master/console/#/master/events, code_id=568c7dc2-8801-400b-a44e-addf82e77498, username=sf, authSessionParentId=568c7dc2-8801-400b-a44e-addf82e77498, authSessionTabId=MO_vSyYhWjg

In the keycloak event settings I have selected kafka.

image image

Do you have any ideas? Thanks in advance!

Adding this project in the list of extensions at keycloak.org

Hi @SnuK87,

I'm one of the developers behind Keycloak.

Your project is really interesting and may help many others that also need to optimize how events are processed and stored.

I see a lot of benefits in using a Kafka-based Event Listener Provider, especially when dealing with a huge load of events and how these events are consumed later for audit purposes.

That said, are you interested in adding your project to our site [1]? Is it active and alive?

[1] https://www.keycloak.org/extensions.html

keycloak 21 does not build with this spi

I started getting exceptions when building keycloak 21 with this spi:

2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-1) Finished step "io.quarkus.deployment.steps.MainClassBuildStep#build" in 0 ms
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-6) Finished step "io.quarkus.deployment.steps.ReflectionDiagnosticProcessor#writeReflectionData" in 0 ms
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-1) Dependency of "io.quarkus.deployment.pkg.steps.JarResultBuildStep#buildRunnerJar" finished; 1 remaining
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-6) Dependency of "io.quarkus.deployment.pkg.steps.JarResultBuildStep#buildRunnerJar" finished; 0 remaining
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-1) Starting step "io.quarkus.deployment.pkg.steps.JarResultBuildStep#buildRunnerJar"
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-1) Finished step "io.quarkus.deployment.pkg.steps.JarResultBuildStep#buildRunnerJar" in 0 ms
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-1) Dependency of "io.quarkus.deployment.pkg.steps.JarResultBuildStep#jarOutput" finished; 0 remaining
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-1) Dependency of "io.quarkus.deployment.pkg.steps.AppCDSBuildStep#build" finished; 0 remaining
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-6) Starting step "io.quarkus.deployment.pkg.steps.JarResultBuildStep#jarOutput"
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-6) Finished step "io.quarkus.deployment.pkg.steps.JarResultBuildStep#jarOutput" in 0 ms
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-16) Starting step "io.quarkus.deployment.pkg.steps.AppCDSBuildStep#build"
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-6) End step completed; 1 remaining
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-16) Finished step "io.quarkus.deployment.pkg.steps.AppCDSBuildStep#build" in 0 ms
2023-03-01 12:16:31,767 TRACE [io.quarkus.builder] (build-16) End step completed; 0 remaining
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-16) Thread "Thread[build-16,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-30) Thread "Thread[build-30,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-21) Thread "Thread[build-21,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-20) Thread "Thread[build-20,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-15) Thread "Thread[build-15,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-10) Thread "Thread[build-10,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-11) Thread "Thread[build-11,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-6) Thread "Thread[build-6,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-26) Thread "Thread[build-26,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-5) Thread "Thread[build-5,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-12) Thread "Thread[build-12,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-17) Thread "Thread[build-17,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-1) Thread "Thread[build-1,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-9) Thread "Thread[build-9,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-19) Thread "Thread[build-19,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-7) Thread "Thread[build-7,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-24) Thread "Thread[build-24,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-22) Thread "Thread[build-22,5,]" exiting
2023-03-01 12:16:31,767 TRACE [org.jboss.threads] (build-2) Thread "Thread[build-2,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-23) Thread "Thread[build-23,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-3) Thread "Thread[build-3,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-25) Thread "Thread[build-25,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-29) Thread "Thread[build-29,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-4) Thread "Thread[build-4,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-28) Thread "Thread[build-28,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-27) Thread "Thread[build-27,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-18) Thread "Thread[build-18,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-8) Thread "Thread[build-8,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-14) Thread "Thread[build-14,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-13) Thread "Thread[build-13,5,]" exiting
2023-03-01 12:16:31,768 TRACE [org.jboss.threads] (build-31) Thread "Thread[build-31,5,]" exiting
ERROR: Failed to run 'build' command.
Error details:
java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doReaugment(QuarkusEntryPoint.java:84)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:48)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:32)
	at org.keycloak.quarkus.runtime.cli.command.Build.run(Build.java:71)
	at picocli.CommandLine.executeUserObject(CommandLine.java:1939)
	at picocli.CommandLine.access$1300(CommandLine.java:145)
	at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
	at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
	at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
	at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
	at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
	at picocli.CommandLine.execute(CommandLine.java:2078)
	at org.keycloak.quarkus.runtime.cli.Picocli.runReAugmentation(Picocli.java:183)
	at org.keycloak.quarkus.runtime.cli.Picocli.runReAugmentationIfNeeded(Picocli.java:120)
	at org.keycloak.quarkus.runtime.cli.Picocli.parseAndRun(Picocli.java:88)
	at org.keycloak.quarkus.runtime.KeycloakMain.main(KeycloakMain.java:88)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:61)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:32)
Caused by: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step org.keycloak.quarkus.deployment.KeycloakProcessor#setCryptoProvider threw an exception: java.lang.LinkageError: loader constraint violation: loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @14faa38c wants to load class org.keycloak.common.crypto.FipsMode. A different class with the same name was previously loaded by java.net.URLClassLoader @614df0a4. (org.keycloak.common.crypto.FipsMode is in unnamed module of loader java.net.URLClassLoader @614df0a4, parent loader 'app')
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:495)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:455)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:467)
	at io.quarkus.deployment.recording.BytecodeRecorderImpl$$RecordingProxyProxy6.setCryptoProvider(Unknown Source)
	at org.keycloak.quarkus.deployment.KeycloakProcessor.setCryptoProvider(KeycloakProcessor.java:636)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
	at java.base/java.lang.Thread.run(Thread.java:833)
	at org.jboss.threads.JBossThread.run(JBossThread.java:501)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:335)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.createProductionApplication(AugmentActionImpl.java:175)
	at io.quarkus.deployment.mutability.ReaugmentTask.main(ReaugmentTask.java:69)
	... 26 more
Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step org.keycloak.quarkus.deployment.KeycloakProcessor#setCryptoProvider threw an exception: java.lang.LinkageError: loader constraint violation: loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @14faa38c wants to load class org.keycloak.common.crypto.FipsMode. A different class with the same name was previously loaded by java.net.URLClassLoader @614df0a4. (org.keycloak.common.crypto.FipsMode is in unnamed module of loader java.net.URLClassLoader @614df0a4, parent loader 'app')
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:495)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:455)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:467)
	at io.quarkus.deployment.recording.BytecodeRecorderImpl$$RecordingProxyProxy6.setCryptoProvider(Unknown Source)
	at org.keycloak.quarkus.deployment.KeycloakProcessor.setCryptoProvider(KeycloakProcessor.java:636)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
	at java.base/java.lang.Thread.run(Thread.java:833)
	at org.jboss.threads.JBossThread.run(JBossThread.java:501)
	at io.quarkus.builder.Execution.run(Execution.java:123)
	at io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:79)
	at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:160)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:331)
	... 28 more
Caused by: java.lang.LinkageError: loader constraint violation: loader io.quarkus.bootstrap.classloading.QuarkusClassLoader @14faa38c wants to load class org.keycloak.common.crypto.FipsMode. A different class with the same name was previously loaded by java.net.URLClassLoader @614df0a4. (org.keycloak.common.crypto.FipsMode is in unnamed module of loader java.net.URLClassLoader @614df0a4, parent loader 'app')
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:495)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:455)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:467)
	at io.quarkus.deployment.recording.BytecodeRecorderImpl$$RecordingProxyProxy6.setCryptoProvider(Unknown Source)
	at org.keycloak.quarkus.deployment.KeycloakProcessor.setCryptoProvider(KeycloakProcessor.java:636)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:909)
	at io.quarkus.builder.BuildContext.run(BuildContext.java:281)
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
	at java.base/java.lang.Thread.run(Thread.java:833)
	at org.jboss.threads.JBossThread.run(JBossThread.java:501)
The command '/bin/sh -c /opt/keycloak/bin/kc.sh -v build' returned a non-zero code: 1
Cleaning up project directory and file based variables
00:01
ERROR: Job failed: exit code 1

It's hard to establish whether this error is actually caused by a peculiarity of the spi implementation or by some bug in the keycloak itself. The error with fips module is confusing to me - we don't use it and never activated it.

I created an issue in the keycloak repository about this and one of the contributors suggested that the problem is in the spi code itself.
Could you comment on this? If the problem is really with the spi implementation, could you fix it?

P.S.: keycloak/keycloak#16202 is similar to this problem.

Kafka Auth

Hey there, is it possible to run this with auth? I'm trying to make it work with SASL and it always runs into:
javax.security.auth.login.LoginException: unable to find LoginModule class: org.jboss.as.security.remoting.RemotingLoginModule

I assume this has to do with Thread.currentThread().setContextClassLoader(null);.

But I don't know, how to proceed here. Any Ideas?

Update: asked on https://stackoverflow.com/questions/57574901/kafka-java-client-classloader-doesnt-find-sasl-scram-login-class

Configuration is not visible to KafkaEventListenerProviderFactory

Hello

I'm using Keycloak in Kubernetes, using this Helm chart

I'm using add-kafka-config.cli (adjustting config file name) - the configs are added.
Also, I've added environment variables to the pod.

When finally I put a jar into deployments - I receive an error

[org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.deployment.unit."keycloak-kafka-1.1.0-jar-with-dependencies.jar".POST_MODULE: org.jboss.msc.service.StartException in service jboss.deployment.unit."keycloak-kafka-1.1.0-jar-with-dependencies.jar".POST_MODULE: WFLYSRV0153: Failed to process phase POST_MODULE of deployment "keycloak-kafka-1.1.0-jar-with-dependencies.jar"
        at [email protected]//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:189)
        at [email protected]//org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1739)
        at [email protected]//org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1701)
        at [email protected]//org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1559)
        at [email protected]//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at [email protected]//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
        at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
        at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1363)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.NullPointerException: topic must not be null.
        at deployment.keycloak-kafka-1.1.0-jar-with-dependencies.jar//com.github.snuk87.keycloak.kafka.KafkaEventListenerProviderFactory.init(KafkaEventListenerProviderFactory.java:56)
        at [email protected]//org.keycloak.services.DefaultKeycloakSessionFactory.loadFactories(DefaultKeycloakSessionFactory.java:297)
        at [email protected]//org.keycloak.services.DefaultKeycloakSessionFactory.deploy(DefaultKeycloakSessionFactory.java:154)
        at [email protected]//org.keycloak.provider.ProviderManagerRegistry.deploy(ProviderManagerRegistry.java:42)
        at [email protected]//org.keycloak.subsystem.server.extension.KeycloakProviderDeploymentProcessor.deploy(KeycloakProviderDeploymentProcessor.java:58)
        at [email protected]//org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:182)
        ... 8 more

Basically Scope config is empty in KafkaEventListenerProviderFactory.init(..)

I've pathced the plugin to read configs parameters directly from environment variables via System.getenv(..) - and this version works just fine.

Could you please help on the issue ? I can use patched version, but I'd prefer to help debugging and fixing it.

standalone.xml or standalone-ha.xml

@SnuK87, congratulations to this project.

During the manual installation it was used standalone.xml and automatic installation (CLI script) used standalone-ha.xml. Why ?, What is the correct ?

Support of Keycloak HA mode

Hello @SnuK87

thanks for your efforts!

We are thinking to use this extension to publish User events e.g. when a user is created.

How will it behave if we scale up the keycloak containers in a cluster and high-availability scenario? As we are serving millions of users, we can not use one single keyloack container.

Is this extension aware of the multiple keycloak instances? To avoid that kafka receives multiple time same event from just another keycloak

If yes, we might use and adjust for usage in
production ☺️
Or you think we shall not use in production?

Thanks!

LOGIN_ERROR event is not published in KAFKA

I can see LOGIN events in the KAFAK topic configured but did not see LOGIN_ERROR event. I have verified that the LOGIN_ERROR is added to KAFKA_EVENTS environment variable.

Enable SASL mechanism for kafkaProducer

Hello dears. I'm totally new to programming and especially Java. I want to enable SASL authentication without ssl and i made this changes in your KafkaProducerFactory.java:

package com.github.snuk87.keycloak.kafka;

import java.util.Map;
import java.util.Properties;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.apache.kafka.common.security.scram.ScramLoginModule;

public final class KafkaProducerFactory {

        private KafkaProducerFactory() {

        }

        public static Producer<String, String> createProducer(String clientId, String bootstrapServer,
            Map<String, Object> optionalProperties) {
                Properties props = new Properties();
                props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServer);
                props.put(ProducerConfig.CLIENT_ID_CONFIG, clientId);
                props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
                props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());

                optionalProperties.forEach(props::put);

                props.put("security.protocol", "SASL_PLAINTEXT");
                props.put("sasl.mechanism", "SCRAM-SHA-512");
                props.put("sasl.jaas.config", "org.apache.kafka.common.security.scram.ScramLoginModule required username=\"user\" password=\"pass\";");

                // fix Class org.apache.kafka.common.serialization.StringSerializer could not be
                // found. see https://stackoverflow.com/a/50981469
                Thread.currentThread().setContextClassLoader(null);

                return new KafkaProducer<>(props);
        }
}

It was built succesfully but when I'm trying to start kafka-spi in keycloak i'm recieving this error:

keycloak_1  | 2023-04-14 14:02:10,403 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-0) Uncaught server error: org.apache.kafka.common.KafkaException: Failed to construct kafka producer
keycloak_1  | 	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:440)
keycloak_1  | 	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:291)
keycloak_1  | 	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:318)
keycloak_1  | 	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:303)
keycloak_1  | 	at com.github.snuk87.keycloak.kafka.KafkaProducerFactory.createProducer(KafkaProducerFactory.java:36)
keycloak_1  | 	at com.github.snuk87.keycloak.kafka.KafkaEventListenerProvider.<init>(KafkaEventListenerProvider.java:53)
keycloak_1  | 	at com.github.snuk87.keycloak.kafka.KafkaEventListenerProviderFactory.create(KafkaEventListenerProviderFactory.java:29)
keycloak_1  | 	at com.github.snuk87.keycloak.kafka.KafkaEventListenerProviderFactory.create(KafkaEventListenerProviderFactory.java:12)
keycloak_1  | 	at org.keycloak.services.DefaultKeycloakSession.getProvider(DefaultKeycloakSession.java:287)
keycloak_1  | 	at jdk.internal.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
keycloak_1  | 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
keycloak_1  | 	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
keycloak_1  | 	at org.jboss.resteasy.core.ContextParameterInjector$GenericDelegatingProxy.invoke(ContextParameterInjector.java:166)
keycloak_1  | 	at com.sun.proxy.$Proxy56.getProvider(Unknown Source)
keycloak_1  | 	at org.keycloak.services.resources.admin.AdminEventBuilder.lambda$addListeners$0(AdminEventBuilder.java:101)
keycloak_1  | 	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
keycloak_1  | 	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
keycloak_1  | 	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
keycloak_1  | 	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
keycloak_1  | 	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
keycloak_1  | 	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
keycloak_1  | 	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
keycloak_1  | 	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
keycloak_1  | 	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
keycloak_1  | 	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
keycloak_1  | 	at org.keycloak.services.resources.admin.AdminEventBuilder.addListeners(AdminEventBuilder.java:100)
keycloak_1  | 	at org.keycloak.services.resources.admin.AdminEventBuilder.refreshRealmEventsConfig(AdminEventBuilder.java:84)
keycloak_1  | 	at org.keycloak.services.resources.admin.RealmAdminResource.updateRealmEventsConfig(RealmAdminResource.java:705)
keycloak_1  | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
keycloak_1  | 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
keycloak_1  | 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
keycloak_1  | 	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
keycloak_1  | 	at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)
keycloak_1  | 	at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:660)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:524)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:474)
keycloak_1  | 	at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:476)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:434)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:192)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:152)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:183)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:141)
keycloak_1  | 	at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:32)
keycloak_1  | 	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
keycloak_1  | 	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
keycloak_1  | 	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
keycloak_1  | 	at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
keycloak_1  | 	at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
keycloak_1  | 	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
keycloak_1  | 	at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
keycloak_1  | 	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:151)
keycloak_1  | 	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:82)
keycloak_1  | 	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:42)
keycloak_1  | 	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
keycloak_1  | 	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
keycloak_1  | 	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
keycloak_1  | 	at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:67)
keycloak_1  | 	at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:55)
keycloak_1  | 	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
keycloak_1  | 	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
keycloak_1  | 	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
keycloak_1  | 	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:380)
keycloak_1  | 	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:358)
keycloak_1  | 	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
keycloak_1  | 	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
keycloak_1  | 	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
keycloak_1  | 	at org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter.lambda$createBlockingHandler$1(QuarkusRequestFilter.java:90)
keycloak_1  | 	at io.vertx.core.impl.ContextImpl.lambda$null$0(ContextImpl.java:159)
keycloak_1  | 	at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)
keycloak_1  | 	at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:157)
keycloak_1  | 	at io.quarkus.vertx.core.runtime.VertxCoreRecorder$13.runWith(VertxCoreRecorder.java:545)
keycloak_1  | 	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
keycloak_1  | 	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
keycloak_1  | 	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
keycloak_1  | 	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
keycloak_1  | 	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
keycloak_1  | 	at java.base/java.lang.Thread.run(Thread.java:829)
keycloak_1  | Caused by: org.apache.kafka.common.KafkaException: javax.security.auth.login.LoginException: No LoginModule found for org.apache.kafka.common.security.scram.ScramLoginModule
keycloak_1  | 	at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:184)
keycloak_1  | 	at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:192)
keycloak_1  | 	at org.apache.kafka.common.network.ChannelBuilders.clientChannelBuilder(ChannelBuilders.java:81)
keycloak_1  | 	at org.apache.kafka.clients.ClientUtils.createChannelBuilder(ClientUtils.java:105)
keycloak_1  | 	at org.apache.kafka.clients.producer.KafkaProducer.newSender(KafkaProducer.java:448)
keycloak_1  | 	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:429)
keycloak_1  | 	... 78 more
keycloak_1  | Caused by: javax.security.auth.login.LoginException: No LoginModule found for org.apache.kafka.common.security.scram.ScramLoginModule
keycloak_1  | 	at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:731)
keycloak_1  | 	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:672)
keycloak_1  | 	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:670)
keycloak_1  | 	at java.base/java.security.AccessController.doPrivileged(Native Method)
keycloak_1  | 	at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:670)
keycloak_1  | 	at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:581)
keycloak_1  | 	at org.apache.kafka.common.security.authenticator.AbstractLogin.login(AbstractLogin.java:60)
keycloak_1  | 	at org.apache.kafka.common.security.authenticator.LoginManager.<init>(LoginManager.java:62)
keycloak_1  | 	at org.apache.kafka.common.security.authenticator.LoginManager.acquireLoginManager(LoginManager.java:105)
keycloak_1  | 	at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:170)
keycloak_1  | 	... 83 more

Please help me understand what am I doing wrong?

Easier deployment of dependencies

It's a bit cumbersome to download and copy all the dependencies into the right place.

Better options might be:

  • Create a jar-with-dependencies
  • Utilize the deployment folder of keycloak

"ssl.endpoint.identification.algorithm=" don`t work

Hello @SnuK87, setting env KAFKA_ENDPOINT_IDENTIFICATION_ALGORITHM= or in keycloak.conf: spi-events-listener-kafka-ssl-endpoint-identification-algorithm= , hasn`t effect, and сertificate continues to be checked.
Can you help with this?

KAFKA_CLIENT_ID=keycloak
KAFKA_ADMIN_TOPIC=raw-keycloak-admin-events
KAFKA_BOOTSTRAP_SERVERS=servers
KAFKA_TOPIC=raw-keycloak-events
KAFKA_SASL_MECHANISM=PLAIN
KAFKA_SECURITY_PROTOCOL=SASL_SSL
KAFKA_SASL_JAAS_CONFIG=org.apache.kafka.common.security.plain.PlainLoginModule required username="username" password="pass";
KAFKA_ENDPOINT_IDENTIFICATION_ALGORITHM=

Keycloak v19 REGISTER_EVENT has NULL for "firstname", "lastname" after activating declarative-user-profile

Hello @SnuK87

we are a bit lost and need your advice.
We are using this extension successfully with older KC versions. Since the migration to KC v19 and after activating
the feature "declarative-user-profiles" and setting User Profile to ON in the Realm, we are getting in our Register Event NULL for both fields.

We are trying to understand why this happens. Can it be that some SPIs and APIs used in the current implementation of the extension are now deprecated or causing this problem?

Many thanks for your help.
BR Mehmet

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.