嵌入式Keycloak Spring Boot应用,将Keycloak从12升级到14。

7

你好,我有一个使用嵌入式Keycloak创建的SpringBoot应用程序,参考了以下示例:https://www.baeldung.com/keycloak-embedded-in-spring-boot-app

我正在尝试将Keycloak从12升级到14,并将resteasy升级到3.15.1.Final,infinispan升级到11.0.9.Final。应用程序无法启动,日志中除了NullPointerException之外没有更多信息。我想知道是否有人尝试过相同操作并有任何建议,因为日志中没有太多信息。谢谢

2021-07-07 10:02:05 [main] INFO  org.keycloak.services - KC-SERVICES0050: Initializing master realm
2021-07-07 10:02:07 [main] DEBUG org.keycloak.keys.GeneratedRsaKeyProviderFactory - Generated keys for master
2021-07-07 10:02:07 [main] DEBUG org.keycloak.keys.GeneratedHmacKeyProviderFactory - Generated secret for master
2021-07-07 10:02:07 [main] DEBUG org.keycloak.keys.GeneratedAesKeyProviderFactory - Generated secret for master
2021-07-07 10:02:07 [main] DEBUG org.keycloak.connections.jpa.updater.liquibase.lock.LiquibaseDBLockProvider - Going to release database lock namespace=KEYCLOAK_BOOT
2021-07-07 10:02:07 [main] DEBUG org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockService - Going to release database lock
2021-07-07 10:02:07 [main] DEBUG org.keycloak.models.cache.infinispan.InfinispanUserCacheProviderFactory - Registered cluster listeners
2021-07-07 10:02:07 [main] DEBUG org.keycloak.executors.DefaultExecutorsProviderFactory - We are in managed environment. Executor 'java:jboss/ee/concurrency/executor/default' was available.
2021-07-07 10:02:07 [main] DEBUG org.keycloak.executors.DefaultExecutorsProviderFactory - Found executor for 'storage-provider-threads' under JNDI name 'java:jboss/ee/concurrency/executor/storage-provider-threads'
2021-07-07 10:02:07 [main] FATAL org.keycloak.services - java.lang.NullPointerException

2021-07-07 10:02:07 [main] DEBUG org.keycloak.executors.DefaultExecutorsProviderFactory - Found executor for 'storage-provider-threads' under JNDI name 'java:jboss/ee/concurrency/executor/storage-provider-threads'
$$$$$$$$$$$$$$$$Stachtrace$$$$$$$$$$$$$ : java.lang.NullPointerException
    at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
    at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
    at org.keycloak.executors.DefaultExecutorsProviderFactory.getExecutor(DefaultExecutorsProviderFactory.java:113)
    at org.keycloak.executors.DefaultExecutorsProviderFactory$1.getExecutor(DefaultExecutorsProviderFactory.java:68)
    at org.keycloak.utils.ServicesUtils.timeBoundOne(ServicesUtils.java:71)
    at org.keycloak.storage.AbstractStorageManager.mapEnabledStorageProvidersWithTimeout(AbstractStorageManager.java:135)
    at org.keycloak.storage.UserStorageManager.getUsersCount(UserStorageManager.java:374)
    at org.keycloak.models.cache.infinispan.UserCacheSession.getUsersCount(UserCacheSession.java:545)
    at org.keycloak.storage.user.UserQueryProvider.getUsersCount(UserQueryProvider.java:52)
    at org.keycloak.services.managers.ApplianceBootstrap.createMasterRealmUser(ApplianceBootstrap.java:99)
3个回答

8
我们在将嵌入式Keycloak升级至15时,在Spring Boot/Servlet风格的应用程序中遇到了类似的模糊错误消息。但是,我们通过查看此教程所基于的项目代码/历史记录(baeldung.com教程)以及thomasdarimont的嵌入式Keycloak服务器在Spring Boot应用程序中运行来最终解决了这些问题。该存储库比初始教程更新了几个版本,可以升级到Keycloak 13。我们将历史记录与我们的代码进行比较,并对每个从keycloak 11到13的版本逐步应用/测试修复程序。之后,从13到15的更新更容易理解,错误也不那么难以理解。
我们的应用程序与Baeldung教程中给出的示例代码并不完全相同,但以下是我们需要升级为Keycloak 15.0.1所做的更改列表。这些更改可能与你的项目不完全一致,但希望这能够帮助某些人节省时间。
  • In KeycloakApplication moved the realm-setup functions from constructor method to bootstrap() method. (An example fix found here)

    
    public class EmbeddedKeycloakApplication extends KeycloakApplication {
    ...

     //public EmbeddedKeycloakApplication() {
     //    createMasterRealmAdminUser();
     //    createBaeldungRealm();
     //}
    
     @Override
     protected ExportImportManager bootstrap() {
         final ExportImportManager exportImportManager = super.bootstrap();
         createMasterRealmAdminUser();
         createBaeldungRealm();
         return exportImportManager;
     }
    

  • In the EmbeddedKeycloakConfig we added a couple new bean references/factories (Both found here)

    public class EmbeddedKeycloakConfig { ...

     @Bean("fixedThreadPool")
     public ExecutorService fixedThreadPool() {
         return Executors.newFixedThreadPool(5);
     }
    
     @Bean
     @ConditionalOnMissingBean(name = "springBootPlatform")
     protected SimplePlatformProvider springBootPlatform() {
         return (SimplePlatformProvider) Platform.getPlatform();
     }
    

  • In our keycloak-server.json, we removed the default 'concurrenthashmap' name from the mapStorage provider, but still provided the concurrenthashmap properties. This matches other Keycloak 15 examples. As Paul mentioned, the map_storage needs to be enabled, and the simplest solution is to use the system properties -Dkeycloak.profile.feature.map_storage=enabled -Dkeycloak.mapStorage.provider=concurrenthashmap. Similar examples can be found in the Keycloak test suites here and here . HOWEVER: We ran into errors when using these system properties, and decided it is not needed for our code. Luckilly, the 'mapStorage' is no specifically called out in the tutorial; it is only found in the Referenced Tutorial Code. So we simply matched other Keycloak 13+ examples and removed the reference in the keycloak-server.json (shown below) to get rid of the null pointer exception.

    //Change this:

     "mapStorage": {
         "provider": "${keycloak.mapStorage.provider:concurrenthashmap}",
         "concurrenthashmap": {
             "dir": "${project.build.directory:target}"
         }
     },
    

    //To This

     "mapStorage": {
         "provider": "${keycloak.mapStorage.provider:}",
         "concurrenthashmap": {
             "dir": "${project.build.directory:target}"
         } 
     },
    

  • Upgraded the proper infinispan and rest versions with keycloak version. (Tutorial code reference)

    < properties>

     < keycloak.version>15.0.1</keycloak.version>
    
     < !-- these should be updated together with Keycloak -->
     < !-- check keycloak-dependencies-server-all effective pom -->
     < infinispan.version>11.0.9.Final</infinispan.version>
     < resteasy.version>3.15.1.Final/resteasy.version>
    

    < /properties>

  • We also added the temp directory location in the SimplePlatformProvider, since this field was required. NOTE: The system temp folder, used in the example, is not recommended for production.

     @Override
     public File getTmpDirectory() {
         return System.getProperty("java.io.tmpdir");
     }
    

我希望这些信息对某些人有用,祝你好运!


你们在生产环境中使用嵌入式Keycloak吗? - Hassen Bennour
1
我刚刚按照您的指示更新了Baeldung原始代码的克隆版本,它们几乎让我成功了。至少在使用Keycloak 16.x时,我还必须更改EmbeddedKeycloakConfig中的mockJndiProvider,以便在查询任何以java:jboss/ee/concurrency/executor/开头的字符串时返回ExecutorService。一旦我进行了这个更改,一切都像魔法般地运行起来了。非常感谢! - Philippe Sevestre
你能升级到最新的20.0.0版本或者之前的19.0.0版本吗?如果可以,请提供建议修改。非常感谢! - Varun Sharma
我遇到了这个问题:https://keycloak.discourse.group/t/keycloak-19-0-3-not-able-to-load-any-cryptoprovider/18046 - Varun Sharma

0

我尝试了使用Keycloak 15做同样的事情,结果也是一样的。似乎Keycloak的ConcurrentHashMapStorageProvider没有被考虑在内。

编辑:在查看Keycloak代码后,我发现MAP_STORAGE功能默认是禁用的(因为该功能被标记为实验性)。要解决此问题,您必须使用以下Java选项启动SpringBoot应用程序:

-Dkeycloak.profile.feature.map_storage=enabled

不幸的是,我现在面临另一个nullPointerException...


0

我已经按照@mrieman建议的更改应用于最初的baeldung.com教程。目前它可以在17.0.1版本的Keycloak上正常工作。希望能对某些人有所帮助。我的Github存储库链接在这里


虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。-【来自审查】 - Prasanth Rajendran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接