cooperlyt / keycloak-phone-provider

A Keycloak provider for phone and SMS
MIT License
252 stars 147 forks source link

Cannot invoke "String.toLowerCase()" because the return value of "org.keycloak.models.RealmModel.getDisplayName()" is null #79

Closed Jeff-Tian closed 9 months ago

Jeff-Tian commented 9 months ago

Docker 方式启动后尝试手机号验证码登录,报如下错误:

keycloak-heroku-keycloak-1  | 2023-09-28 06:52:41,223 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-11) Uncaught server error: java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because the return value of "org.keycloak.models.RealmModel.getDisplayName()" is null
keycloak-heroku-keycloak-1  |   at cc.coopersoft.keycloak.phone.providers.sender.AliyunSmsSenderServiceProvider.sendSmsMessage(AliyunSmsSenderServiceProvider.java:50)
keycloak-heroku-keycloak-1  |   at cc.coopersoft.keycloak.phone.providers.spi.impl.DefaultPhoneProvider.sendTokenCode(DefaultPhoneProvider.java:135)
keycloak-heroku-keycloak-1  |   at cc.coopersoft.keycloak.phone.providers.rest.TokenCodeResource.getTokenCode(TokenCodeResource.java:57)
keycloak-heroku-keycloak-1  |   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
keycloak-heroku-keycloak-1  |   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
keycloak-heroku-keycloak-1  |   at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
keycloak-heroku-keycloak-1  |   at java.base/java.lang.reflect.Method.invoke(Method.java:568)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:660)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:524)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:474)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:476)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:434)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:192)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:152)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:183)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:141)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:32)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
keycloak-heroku-keycloak-1  |   at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
keycloak-heroku-keycloak-1  |   at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
keycloak-heroku-keycloak-1  |   at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:151)
keycloak-heroku-keycloak-1  |   at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:82)
keycloak-heroku-keycloak-1  |   at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:42)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
keycloak-heroku-keycloak-1  |   at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:84)
keycloak-heroku-keycloak-1  |   at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:71)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
keycloak-heroku-keycloak-1  |   at io.quarkus.vertx.http.runtime.VertxHttpRecorder$6.handle(VertxHttpRecorder.java:430)
keycloak-heroku-keycloak-1  |   at io.quarkus.vertx.http.runtime.VertxHttpRecorder$6.handle(VertxHttpRecorder.java:408)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
keycloak-heroku-keycloak-1  |   at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
keycloak-heroku-keycloak-1  |   at org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter.lambda$createBlockingHandler$0(QuarkusRequestFilter.java:82)
keycloak-heroku-keycloak-1  |   at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
keycloak-heroku-keycloak-1  |   at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
keycloak-heroku-keycloak-1  |   at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
keycloak-heroku-keycloak-1  |   at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
keycloak-heroku-keycloak-1  |   at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
keycloak-heroku-keycloak-1  |   at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
keycloak-heroku-keycloak-1  |   at java.base/java.lang.Thread.run(Thread.java:833)
keycloak-heroku-keycloak-1  |
keycloak-heroku-keycloak-1  |
image

已经按照 README 配置完成,在登录时,获取验证码时出错:

image

更多信息:

Docker compose 文件

version: '3'

services:
  keycloak:
      build: 
        context: .
        dockerfile: Dockerfile.local
      environment:
        KEYCLOAK_ADMIN: admin
        KEYCLOAK_ADMIN_PASSWORD: admin
        PORT: 8080
        DB_VENDOR: "h2"
      ports:
        - "8080:8080"
        - "9990:9990"
      volumes:
        - ~/.m2/repository:/root/.m2/repository

Dockerfile 文件:

ARG KEYCLOAK_VERSION=21.0.1

FROM quay.io/keycloak/keycloak:${KEYCLOAK_VERSION} as builder

COPY idps/phone/keycloak-phone-provider.jar /opt/keycloak/providers/
COPY idps/phone/keycloak-phone-provider.resources.jar /opt/keycloak/providers/
COPY idps/phone/keycloak-sms-provider-aliyun.jar /opt/keycloak/providers/

ENV KC_HOSTNAME_STRICT=false
ENV KC_HOSTNAME_STRICT_HTTPS=false
ENV KC_HTTP_ENABLED=true

USER 1000

RUN /opt/keycloak/bin/kc.sh build --health-enabled=true

FROM quay.io/keycloak/keycloak:$KEYCLOAK_VERSION
COPY --from=builder /opt/keycloak/ /opt/keycloak/
WORKDIR /opt/keycloak

ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start-dev", "--spi-phone-default-service=aliyun", "--spi-message-sender-service-aliyun-region=cn-hangzhou", "--spi-message-sender-service-aliyun-key=xxxxxx", "--spi-message-sender-service-aliyun-secret=yyyyyy", "--spi-message-sender-service-aliyun-otp-template=SMS_136861653", "--hostname-strict=false", "--features=\"preview,scripts\"", "--log-level=INFO"]

Reaml partial export json:

realm-export.json.zip

Jeff-Tian commented 9 months ago

了解了,应该是 DisplayName 没有配置导致的:

image