Keycloak.X: MSSQL db connection string construction issue
See original GitHub issueDescribe the bug
Checking out Keycloak.x 16.1.1 with openjdk 11.0.14 on Debian 10.
I was trying to connect to MSSQL database with the following configuration in keycloak.properties
:
db=mssql
db.username=user
db.password=pw
db.url=jdbc:sqlserver://mydbserver;databaseName=MyDb;
Executing show-config
displays that when the actual kc.db.url
is constructed, jdbc:mssql
is used instead of the configured jdbc:sqlserver
.
./bin/kc.sh show-config
Current Profile: none
Runtime Configuration:
kc.db = mssql (PersistedConfigSource)
kc.db.password = ******* (PersistedConfigSource)
kc.db.url = jbcd:mssql://mydbserver/MyDb(PersistedConfigSource)
kc.db.username = user(PersistedConfigSource)
kc.version = 16.1.1 (KcSysPropConfigSource)
This in turn causes problems with MSSQL JDBC driver, which seems to very much expect the jdbc:sqlserver
part.
./bin/kc.sh start-dev
WARN [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: keycloak-default) HHH000342: Could not obtain connection to query metadata: com.microsoft.sqlserver.jdbc.SQLServerException: The connection string contains a badly formed name or value.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:234)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnectionInternal(SQLServerDataSource.java:1050)
at com.microsoft.sqlserver.jdbc.SQLServerPooledConnection.createNewConnection(SQLServerPooledConnection.java:81)
at com.microsoft.sqlserver.jdbc.SQLServerPooledConnection.<init>(SQLServerPooledConnection.java:56)
at com.microsoft.sqlserver.jdbc.SQLServerXAConnection.<init>(SQLServerXAConnection.java:36)
at com.microsoft.sqlserver.jdbc.SQLServerXADataSource.getXAConnection(SQLServerXADataSource.java:60)
at com.microsoft.sqlserver.jdbc.SQLServerXADataSource.getXAConnection(SQLServerXADataSource.java:92)
at io.agroal.pool.ConnectionFactory.createConnection(ConnectionFactory.java:210)
at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:509)
at io.agroal.pool.ConnectionPool$CreateConnectionTask.call(ConnectionPool.java:490)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at io.agroal.pool.util.PriorityScheduledExecutor.beforeExecute(PriorityScheduledExecutor.java:75)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1126)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Finally, I figured out that if I start the server supplying the --db-url
as a runtime parameter, the sqlserver
seems to not get overwritten despite the mssql
driver obviously being used, and connection proceeds as expected (tries to connect to the correct server).
./bin/kc.sh start-dev --db-url jdbc:sqlserver://mydbserver
With this config, the connection now fails due to invalid credentials (trying to log in as sa
user). Adding credentials as runtime parameters as well, the connection proceeds further. This time, it fails to create a lock table on master
database (default, as I am now not supplying the database name).
./bin/kc.sh start-dev --db-url jdbc:sqlserver://mydbserver --db-username user --db-password pw
ERROR [org.key.qua.run.cli.ExecutionExceptionHandler] (main) ERROR: liquibase.exception.DatabaseException: CREATE TABLE permission denied in database 'master'. [Failed SQL: CREATE TABLE [guest].[DATABASECHANGELOGLOCK] ([ID] [int] NOT NULL, [LOCKED] [bit] NOT NULL, [LOCKGRANTED] [datetime2](3), [LOCKEDBY] [nvarchar](255), CONSTRAINT [PK_DATABASECHANGELOGLOCK] PRIMARY KEY ([ID]))]
I am now stuck, as neither of the two possibilities for supplying the correct database name seem to work.
The --db-url-database
seems to get ignored:
./bin/kc.sh start-dev --db-url jdbc:sqlserver://mydbserver --db-username user --db-password pw --db-url-database MyDb
ERROR [org.key.qua.run.cli.ExecutionExceptionHandler] (main) ERROR: liquibase.exception.DatabaseException: CREATE TABLE permission denied in database 'master'. [Failed SQL: CREATE TABLE [guest].[DATABASECHANGELOGLOCK] ([ID] [int] NOT NULL, [LOCKED] [bit] NOT NULL, [LOCKGRANTED] [datetime2](3), [LOCKEDBY] [nvarchar](255), CONSTRAINT [PK_DATABASECHANGELOGLOCK] PRIMARY KEY ([ID]))]
And using databaseName
in the actual URL drops the username parameter, reverting to log in as sa
again.
./bin/kc.sh start-dev --db-url jdbc:sqlserver://mydbserver;databaseName=MyDb; --db-username user --db-password pw
WARN [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: keycloak-default) HHH000342: Could not obtain connection to query metadata: com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'sa'
Finally, supplying everything that should be necessary in the --db-url
still makes it attempt to log in as sa
.
./bin/kc.sh start-dev --db-url jdbc:sqlserver://mydbserver;databaseName=MyDb;username=user;password=pw;
WARN [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: keycloak-default) HHH000342: Could not obtain connection to query metadata: com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'sa'.
I am at a loss and unable to proceed.
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
@pedroigor indeed, I’m happy to be your test subject. 😃 Carry on the good work!
@epuronta Not really. Your mistake is a signal that we are failing to make it trivial to use 😃