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 Related StackOverflow Question
@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 😃