mysql - 如何让 Keycloak 连接到 MySQL DB?
问题描述
我一直在爬取许多这样的网站,试图让 Keycloak 与 MySQL 持久层一起工作。我正在使用 docker,但我使用的是我自己的图像,因此它从秘密管理器而不是环境变量或 Docker 秘密中提取密码和其他敏感数据。但是,除此之外,这些图像非常接近库存。
无论如何,我已经启动并运行了一个 MySQL 8 容器,并且从 Keycloak 12.0.3 容器中我可以很好地连接到 MySQL 容器:
# mysql -h mysql -u keycloak --password=somethingtochangelater -D keycloak -e "SHOW DATABASES;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| keycloak |
+--------------------+
因此,实例之间的连接没有问题,并且该用户名/密码可以keycloak
正常访问数据库。
然后我运行了几个命令来配置 Keycloak 实例(keycloak 安装在/opt/myco/bin/keycloak
):
/opt/myco/bin/keycloak/bin/standalone.sh &
# Pausing for server startup
sleep 20
# Add mysql module - JDBC driver unpacked at /opt/myco/bin/keycloak-install/mysql-connector-java-8.0.23/mysql-connector-java-8.0.23.jar
/opt/myco/bin/keycloak/bin/jboss-cli.sh --connect --command="module add --name=com.mysql --dependencies=javax.api,javax.transaction.api --resources=/opt/myco/bin/keycloak-install/mysql-connector-java-8.0.23/mysql-connector-java-8.0.23.jar --module-root-dir=/opt/myco/bin/keycloak/modules/system/layers/keycloak/"
# Removing h2 datasource
/opt/myco/bin/keycloak/bin/jboss-cli.sh --connect --command="/subsystem=datasources/data-source=KeycloakDS:remove"
# Adding MySQL datasource
/opt/myco/bin/keycloak/bin/jboss-cli.sh --connect --command="/subsystem=datasources/jdbc-driver=mysql:add(driver-name=mysql,driver-module-name=com.mysql,driver-class-name=com.mysql.cj.jdbc.Driver)"
# TODO - add connection pooling options here...
# Configuring data source
/opt/myco/bin/keycloak/bin/jboss-cli.sh --connect --command="data-source add --name=KeycloakDS --jndi-name=java:jboss/datasources/KeycloakDS --enabled=true --password=somethingtochangelater --user-name=keycloak --driver-name=com.mysql --use-java-context=true --connection-url=jdbc:mysql://mysql:3306/keycloak?useSSL=false&characterEncoding=UTF-8"
# Testing connection
/opt/myco/bin/keycloak/bin/jboss-cli.sh --connect --command="/subsystem=datasources/data-source=KeycloakDS:test-connection-in-pool"
# Creating admin user
/opt/myco/bin/keycloak/bin/add-user-keycloak.sh -r master -u "admin" -p "somethingelse"
# Shutting down initial server
/opt/myco/bin/keycloak/bin/jboss-cli.sh --connect command=":shutdown"
这一切似乎运行良好。特别注意test-connection-in-pool
没有问题:
{
"outcome" => "success",
"result" => [true],
"response-headers" => {"process-state" => "reload-required"}
}
但是,当我再次启动服务器备份时,它会崩溃并出现几个异常,首先是:
22:31:52,484 FATAL [org.keycloak.services] (ServerService Thread Pool -- 56) Error during startup: java.lang.RuntimeException: Failed to connect to database
at org.keycloak.keycloak-model-jpa@12.0.3//org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory.getConnection(DefaultJpaConnectionProviderFactory.java:377)
at org.keycloak.keycloak-model-jpa@12.0.3//org.keycloak.connections.jpa.updater.liquibase.lock.LiquibaseDBLockProvider.lazyInit(LiquibaseDBLockProvider.java:65)
...
它继续运行,尽管我怀疑 Exception 最终是致命的,它最终死于:
22:31:53,114 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 40) WFLYCTL0190: Step handler org.jboss.as.controller.AbstractAddStepHandler$1@33063168 for operation add at address [
("subsystem" => "jca"),
("workmanager" => "default"),
("short-running-threads" => "default")
] failed -- java.util.concurrent.RejectedExecutionException: java.util.concurrent.RejectedExecutionException
at org.jboss.threads@2.4.0.Final//org.jboss.threads.RejectingExecutor.execute(RejectingExecutor.java:37)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.rejectShutdown(EnhancedQueueExecutor.java:2029)
...
该模块/opt/myco/bin/keycloak/modules/system/layers/keycloak/com/mysql/main
具有 jar 文件和 module.xml:
# ls
module.xml mysql-connector-java-8.0.23.jar
# cat module.xml
<?xml version='1.0' encoding='UTF-8'?>
<module xmlns="urn:jboss:module:1.1" name="com.mysql">
<resources>
<resource-root path="mysql-connector-java-8.0.23.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
Standalone.xml 文件对我来说看起来很合理:
...
<subsystem xmlns="urn:jboss:domain:datasources:6.0">
<datasources>
...
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
<connection-url>jdbc:mysql://mysql:3306/keycloak?useSSL=false&characterEncoding=UTF-8</connection-url>
<driver>com.mysql</driver>
<security>
<user-name>keycloak</user-name>
<password>somethingtochangelater</password>
</security>
</datasource>
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
<driver name="mysql" module="com.mysql">
<driver-class>com.mysql.cj.jdbc.Driver</driver-class>
</driver>
</drivers>
</datasources>
...
所以....有人知道发生了什么吗?我还需要做什么才能让 Keycloak 正确地与 MySQL 对话?我还能做些什么来调试问题所在?
解决方案
不确定您的特定情况有什么问题,但我使用了 jboss/keycloak 图像,它可以很好地连接到 MySQL。也许您可以从那里获得您的自定义图像。我的博客文章中的完整设置https://link.medium.com/eK6IRducpeb
推荐阅读
- flutter - 如何检测 Flutter 上 ListView 滚动位置的中间或四分之三以延迟加载数据?
- java - 如何在使用 EventSource 库与 SSE 建立连接时传递标头
- laravel - 如何在 Laravel 的 hasManyThrough 关系中删除 laravel_through_key
- javascript - 如何使一个数组的属性成为另一个数组的属性(代码优化)
- javascript - 将选项附加到引导双重列表
- scala - spark中groupBy/join操作的意外缓存行为
- python - 如何在 Python 中读取输入文件并转换为数组
- vb.net - VB Net Graphics DrawString 构造失败
- jquery - 使用自定义按钮增加数字输入的值
- excel - 使用 blob url 以 Angular 7 下载 excel 文件