部署keycloak自定义spi部署

Posted

技术标签:

【中文标题】部署keycloak自定义spi部署【英文标题】:Deploy keycloak custom spi deployment 【发布时间】:2020-01-08 17:36:31 【问题描述】:

我尝试创建一个自定义 spi,在我的 keycloak 项目中,遵循基本的 keycloack 结构,我添加自定义提供程序接口,扩展提供程序,自定义提供程序工厂并为他们实现自定义 spi,如 keycloak 文档所述,他们在他们的源代码,之后我为我的提供者和提供者工厂创建了一个自定义实现,我按照文档所述在 META-INF/services 中创建文件,并且我正在使用 ear aproach 进行部署,就像在 beercloak 示例中一样,但是当我尝试使用抛出了代码中的提供程序空指针异常,这仅在我尝试添加自定义 spi 时发生,如果我正在实现具有现有 keycloak spi 的提供程序,它也可以工作,如果我使用模块方法,它也可以工作,我在哪里创建一个带有 jboss-cli 的新模块,但这种方法似乎很难维护,任何人都知道为什么会发生这种情况,我该如何解决它或者最好的方法是什么,谢谢。

08:43:48,264 WARN [org.keycloak.services](默认任务 1)KC-SERVICES0013:身份验证失败:java.lang.NullPointerException 在 sso.authentication.forms.RegistrationProfile.validate(RegistrationProfile.java:55) 在 org.keycloak.authentication.FormAuthenticationFlow.processAction(FormAuthenticationFlow.java:214) 在 org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:99) 在 org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:873) 在 org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:296) 在 org.keycloak.services.resources.LoginActionsService.processRegistration(LoginActionsService.java:631) 在 org.keycloak.services.resources.LoginActionsService.registerRequest(LoginActionsService.java:685) 在 org.keycloak.services.resources.LoginActionsService.processRegister(LoginActionsService.java:665) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:138) 在 org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:517) 在 org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:406) 在 org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:370) 在 org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:355) 在 org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:372) 在 org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:344) 在 org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137) 在 org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100) 在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:440) 在 org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229) 在 org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135) 在 org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:355) 在 org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138) 在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215) 在 org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227) 在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) 在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:791) 在 io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) 在 org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90) 在 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) 在 io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) 在 io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) 在 io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) 在 io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) 在 io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) 在 org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) 在 io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) 在 io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) 在 io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) 在 io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) 在 io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) 在 io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) 在 io.undertow.servlet.handlers.ServletInitialHandler.access 100 美元(ServletInitialHandler.java:81) 在 io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) 在 io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) 在 io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) 在 io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) 在 org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105) 在 org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502) 在 org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502) 在 org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502) 在 org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502) 在 io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) 在 io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) 在 io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) 在 io.undertow.server.Connectors.executeRootHandler(Connectors.java:364) 在 io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) 在 org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) 在 org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982) 在 org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) 在 org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377) 在 java.lang.Thread.run(Thread.java:748)

【问题讨论】:

您能否使用收到的错误日志更新您的问题。这样有助于人们了解您在哪里犯了错误或指出出了什么问题。 【参考方案1】:

如果您仔细查看 $JBOSS_HOME/standalone/configuration/standalon-ha.xml$JBOSS_HOME/standalone/configuration/standalon.xml 文件,您会在某处注意到这些行:

<providers>
    <provider>classpath:$jboss.home.dir/providers/*</provider>
</providers>

这意味着,您需要将已编译的文件放在根目录中的文件夹 $jboss.home.dir/providers/ 中,然后才能注册它们的 SPI

这样做基本上与在此处添加带有模块路径的新行相同,例如

<providers>
    <provider>classpath:$jboss.home.dir/providers/*</provider>
    <provider>module:com/selast/keycloak-provider/*</provider>
</providers>

希望它对某人有所帮助,因为我已经花了一天的时间?。

【讨论】:

以上是关于部署keycloak自定义spi部署的主要内容,如果未能解决你的问题,请参考以下文章

如何避免KeyCloak的登录页面,部署我们项目的自定义登录页面?

Keycloak - 自定义 SPI 未出现在列表中

如何在 Kubernetes 上的 Keycloak Operator 部署中使用自定义主题?

如何在 Kubernetes 上的 Keycloak Operator 部署上创建自定义主题?

具有授权的 Keycloak 自定义 SPI REST 端点

在自定义 Keycloak SPI Authenticator 中处理用户的取消