Search code examples
postgresqlvalidationjdbckeycloakquarkus

Keycloak with Quarkus datasource configuration with validation attributes


I'd like config jdbc with validation like this (on wildfly):

<validation>
     <check-valid-connection-sql>select 1</check-valid-connection-sql>
     <validate-on-match>false</validate-on-match>
     <background-validation-millis>10000</background-validation-millis>
</validation>

I can't config it on Keycloak. There is possible if I config a Quarkus datasource. But i'm afraid Keycloak can't use on quarkus configured datasorce...

Can I some way config validationQuery, and it's running attributes? Can Keyclok work with Quarkus create datasource? How can I config JDBC_PING and keycloak datasource simple and secure. (without plaintext password or ssl)

Thank's a lot.


Solution

  • Keycloak map KC prefixed properties to quarkus properties. The class is :

    org.keycloak.quarkus.runtime.configuration.mappers.DatabasePropertyMappers on

    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-quarkus-server</artifactId>
    </dependency>
    

    So keycloak's datasource should be quarkus datasource!

    You can use these environment variables:

    SET QUARKUS_DATASOURCE_JDBC_VALIDATION_QUERY_SQL=select 1
    SET QUARKUS_DATASOURCE_JDBC_BACKGROUND_VALIDATION_INTERVAL=10
    SET QUARKUS_DATASOURCE_JDBC_FOREGROUND_VALIDATION_INTERVAL=10
    

    Other interesting thing, that JNDI doesn't supported by quarkus, so JDBC_PING cannot parameterized by datasource_jndi_name.

    But you can use environment variables like this:

        <JDBC_PING
            connection_driver="org.postgresql.Driver"
            connection_username="${env.KC_DB_USERNAME}"
            connection_url="${env.KC_DB_URL}"
            initialize_sql="CREATE SCHEMA IF NOT EXISTS ${env.KC_DB_SCHEMA:public}; CREATE TABLE IF NOT EXISTS ${env.KC_DB_SCHEMA:public}.JGROUPSPING (own_addr varchar(200) NOT NULL, cluster_name varchar(200) NOT NULL, bind_addr varchar(200) NOT NULL, updated timestamp default current_timestamp, ping_data BYTEA, constraint PK_JGROUPSPING PRIMARY KEY (own_addr, cluster_name));"
            insert_single_sql="INSERT INTO ${env.KC_DB_SCHEMA:public}.JGROUPSPING (own_addr, cluster_name, bind_addr, updated, ping_data) values (?, ?, '${env.JGROUPS_DISCOVERY_EXTERNAL_IP:127.0.0.1}', NOW(), ?);"
            delete_single_sql="DELETE FROM ${env.KC_DB_SCHEMA:public}.JGROUPSPING WHERE own_addr=? AND cluster_name=?;"
            select_all_pingdata_sql="SELECT ping_data, own_addr, cluster_name FROM ${env.KC_DB_SCHEMA:public}.JGROUPSPING WHERE cluster_name=?"
            info_writer_sleep_time="500"
            remove_all_data_on_view_change="true"
            stack.combine="REPLACE"
            stack.position="MPING"
        />
    

    SSL and other settings you could set as jdbc_url parameter. Here is some description: https://jdbc.postgresql.org/documentation/use/