Keycloak Spring 多租户空指针异常

Posted

技术标签:

【中文标题】Keycloak Spring 多租户空指针异常【英文标题】:Keycloak Spring Multitenant Null Pointer Exception 【发布时间】:2019-08-11 04:48:50 【问题描述】:

源代码来自:https://github.com/ineat/spring-keycloak-multitenant

按照自述文件中的说明启动 Keycloak 并添加领域。

在各个地方更新了 Keycloak Json 代码。

启动 Spring 项目。

调用“http://localhost:8081/multitenant”时出现以下异常:

2019-03-20 18:34:28.195 错误 25640 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost]:异常处理 /多租户

2019-03-20 18:34:28.248 错误 25640 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] :Servlet.service() for servlet [dispatcherServlet] 抛出异常

2019-03-20 18:34:28.249 错误 25640 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost]:异常处理 ErrorPage[errorCode=0, location=/error]

2019-03-20 18:34:28.251 错误 25640 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] :Servlet.service() for servlet [dispatcherServlet] 抛出异常

2019-03-20 18:34:28.252 错误 25640 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost]:异常处理 ErrorPage[errorCode=0, location=/error]

2019-03-20 18:34:28.506 错误 25640 --- [nio-8081-exec-2] o.a.c.c.C.[Tomcat].[localhost]:异常处理 /favicon.ico

2019-03-20 18:34:28.511 错误 25640 --- [nio-8081-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] :Servlet.service() for servlet [dispatcherServlet] 抛出异常

2019-03-20 18:34:28.512 错误 25640 --- [nio-8081-exec-2] o.a.c.c.C.[Tomcat].[localhost]:异常处理 ErrorPage[errorCode=0, location=/error]

2019-03-20 18:34:28.514 错误 25640 --- [nio-8081-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] :Servlet.service() for servlet [dispatcherServlet] 抛出异常

2019-03-20 18:34:28.515 错误 25640 --- [nio-8081-exec-2] o.a.c.c.C.[Tomcat].[localhost]:异常处理 ErrorPage[errorCode=0, location=/error]

java.lang.NullPointerException: null at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) ~[na:1.8.0_191] 在 java.util.concurrent.ConcurrentHashMap.containsKey(ConcurrentHashMap.java:964) ~[na:1.8.0_191] 在 com.ineat.spring.keycloak.multitenant.HeaderBasedConfigResolver.resolve(HeaderBasedConfigResolver.java:21) 〜[类/:na]在 org.keycloak.adapters.AdapterDeploymentContext.resolveDeployment(AdapterDeploymentContext.java:88) ~[keycloak-adapter-core-4.4.0.Final.jar:4.4.0.Final] 在 org.keycloak.adapters.PreAuthActionsHandler.preflightCors(PreAuthActionsHandler.java:107) ~[keycloak-adapter-core-4.4.0.Final.jar:4.4.0.Final] 在 org.keycloak.adapters.PreAuthActionsHandler.handleRequest(PreAuthActionsHandler.java:79) ~[keycloak-adapter-core-4.4.0.Final.jar:4.4.0.Final] 在 org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:81) ~[keycloak-spring-security-adapter-4.4.0.Final.jar:4.4.0.Final] 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) ~[spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE] 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) ~[spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE] 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) ~[spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE] 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.0.9.RELEASE.jar:5.0.9.RELEASE] 在 org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) ~[spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE] 在 org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) ~[spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728) ~[tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:472) ~[tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:395) ~[tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316) ~[tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:395) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:254) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:349) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:175) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191] 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191] 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.34.jar:8.5.34] 在 java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]

请告知是否需要进行更多配置/我应该修复的任何错误。

提前致谢。

【问题讨论】:

【参考方案1】:

您提到的 spring-boot 应用程序根据标头字段(即“realm:ORGA1”)解析并加载多租户的 keycloak 配置。

但不知道你为什么打电话给http://localhost:8081/multitenant

您应该获取所需租户的令牌,然后通过在请求的标头中传递正确的租户来调用 API

【讨论】:

以上是关于Keycloak Spring 多租户空指针异常的主要内容,如果未能解决你的问题,请参考以下文章

SpringBug记录 -- java.lang.NullPointerException在Spring单元测试中遇到的空指针异常及依赖注入异常总结

Spring自动装配空指针异常[重复]

Spring Boot Keycloak 多租户配置

Spring Security 3.1 + JPA - 空指针异常

Spring Autowired空指针异常

空指针异常。 Spring 安全过滤器失败