java.lang.ClassNotFoundException when running Keycloak with an spi that is using Akka
by Jonas Schönenberger
Hi everyone
I am writing an Keycloak SPI that will modify clients based on events.
Therefore I use the EventListenerProvider. In the SPI code, that is written
in Scala, I am using the Akka library for certain tasks. Unfortunately I
get an ClassNotFoundException for the class
akka.event.DefaultLoggingFilter when I run Keycloak with the spi. I've
built an spi before, that is not using Akka and it worked.
The class is available inside the spi .jar-file. I found a ticket on
Keycloak's Jira Board (https://issues.jboss.org/browse/KEYCLOAK-4738) and
updated to Keycloak version 3.1.0.Final, that contains the fix for this
ticket - didn't help.
Here is the full error message I get:
09:47:49,003 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool
> -- 52) MSC000001: Failed to start service
> jboss.undertow.deployment.default-server.default-host./auth:
> org.jboss.msc.service.StartException in service
> jboss.undertow.deployment.default-server.default-host./auth:
> java.lang.RuntimeException: RESTEASY003325: Failed to construct public
> org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
> at
> org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:85)
> at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
> at java.util.concurrent.FutureTask.run(FutureTask.java:266)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
> at java.lang.Thread.run(Thread.java:745)
> at org.jboss.threads.JBossThread.run(JBossThread.java:320)
> Caused by: java.lang.RuntimeException: RESTEASY003325: Failed to construct
> public
> org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
> at
> org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:162)
> at
> org.jboss.resteasy.spi.ResteasyProviderFactory.createProviderInstance(ResteasyProviderFactory.java:2209)
> at
> org.jboss.resteasy.spi.ResteasyDeployment.createApplication(ResteasyDeployment.java:299)
> at
> org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:240)
> at
> org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.init(ServletContainerDispatcher.java:113)
> at
> org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.init(HttpServletDispatcher.java:36)
> at
> io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:117)
> at
> org.wildfly.extension.undertow.security.RunAsLifecycleInterceptor.init(RunAsLifecycleInterceptor.java:78)
> at
> io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:103)
> at
> io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start(ManagedServlet.java:231)
> at
> io.undertow.servlet.core.ManagedServlet.createServlet(ManagedServlet.java:132)
> at
> io.undertow.servlet.core.DeploymentManagerImpl.start(DeploymentManagerImpl.java:526)
> at
> org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:101)
> at
> org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)
> ... 6 more
> Caused by: java.lang.ClassNotFoundException:
> akka.event.DefaultLoggingFilter from [Module
> "deployment.keycloak-server.war:main" from Service Module Loader]
> at
> org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:198)
> at
> org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
> at
> org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
> at
> org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
> at java.lang.Class.forName0(Native Method)
> at java.lang.Class.forName(Class.java:348)
> at
> akka.actor.ReflectiveDynamicAccess.$anonfun$getClassFor$1(ReflectiveDynamicAccess.scala:21)
> at scala.util.Try$.apply(Try.scala:209)
> at
> akka.actor.ReflectiveDynamicAccess.getClassFor(ReflectiveDynamicAccess.scala:20)
> at
> akka.actor.ReflectiveDynamicAccess.createInstanceFor(ReflectiveDynamicAccess.scala:38)
> at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:758)
> at akka.actor.ActorSystem$.apply(ActorSystem.scala:245)
> at akka.actor.ActorSystem$.apply(ActorSystem.scala:288)
> at akka.actor.ActorSystem$.apply(ActorSystem.scala:263)
> at
> some.package.keycloak.keycloak.REST.KeycloakAdminClient.<init>(REST.scala:592)
> at
> some.package.keycloak.keycloak.KeycloakConfigurator.<init>(KeycloakConfigurator.scala:21)
> at
> some.package.keycloak.MyEventListenerProviderFactory.init(MyEventListenerProvider.scala:50)
> at
> org.keycloak.services.DefaultKeycloakSessionFactory.loadFactories(DefaultKeycloakSessionFactory.java:209)
> at
> org.keycloak.services.DefaultKeycloakSessionFactory.init(DefaultKeycloakSessionFactory.java:76)
> at
> org.keycloak.services.resources.KeycloakApplication.createSessionFactory(KeycloakApplication.java:313)
> at
> org.keycloak.services.resources.KeycloakApplication.<init>(KeycloakApplication.java:110)
> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
> at
> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
> at
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
> at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
> at
> org.jboss.resteasy.core.ConstructorInjectorImpl.construct(ConstructorInjectorImpl.java:150)
> ... 19 more
> 09:47:49,010 ERROR [org.jboss.as.controller.management-operation]
> (Controller Boot Thread) WFLYCTL0013: Operation ("add") failed - address:
> ([("deployment" => "keycloak-server.war")]) - failure description:
> {"WFLYCTL0080: Failed services" =>
> {"jboss.undertow.deployment.default-server.default-host./auth" =>
> "org.jboss.msc.service.StartException in service
> jboss.undertow.deployment.default-server.default-host./auth:
> java.lang.RuntimeException: RESTEASY003325: Failed to construct public
> org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
> Caused by: java.lang.RuntimeException: RESTEASY003325: Failed to
> construct public
> org.keycloak.services.resources.KeycloakApplication(javax.servlet.ServletContext,org.jboss.resteasy.core.Dispatcher)
> Caused by: java.lang.ClassNotFoundException:
> akka.event.DefaultLoggingFilter from [Module
> \"deployment.keycloak-server.war:main\" from Service Module Loader]"}}
Do you guys have an idea what can cause this error and how to solve it?
Thank you for your help and Best Regards
Jonas
7 years, 6 months
Authentication SPI and connection management
by Max Musternam
Hello,
I've followed the instructions from
https://keycloak.gitbooks.io/documentation/server_installation/topics/dat...
But instead of changing the existing DS and provider, I added
another one, because I have to implement additional check and/or actions
against the data in the second database:
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/KeycloakDS"
pool-name="KeycloakDS" enabled="true" use-java-context="true">
...
</datasource>
<datasource jndi-name="java:jboss/datasources/myDbDS"
pool-name="mydb" enabled="true" use-java-context="true">
<connection-url>jdbc:postgresql://192.168.XX.XX/myproject</connection-url>
<driver>postgresql</driver>
<pool>
<max-pool-size>20</max-pool-size>
</pool>
<security>
<user-name>user</user-name>
<password>password</password>
</security>
</datasource>
</datasources>
</subsystem>
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
<spi name="connectionsJpa">
<provider name="default" enabled="true">
...
</provider>
<provider name="mydb" enabled="true">
<properties>
<property name="dataSource"
value="java:jboss/datasources/myDbDS"/>
<property name="initializeEmpty" value="false"/>
<property name="migrationStrategy" value="validate"/>
</properties>
</provider>
</spi>
...
</subsystem>
Now I can't find this connection provider in the admin console. Only the
default is listed in Server Info > Providers. In the log file I've found
initialization of both datasources
(MSC service thread 1-8) WFLYJCA0001: Bound data source
[java:jboss/datasources/KeycloakDS
(MSC service thread 1-1) WFLYJCA0001: Bound data source
[java:jboss/datasources/myDbDS
but only one PersistenceUnit was processed:
HHH000204: Processing PersistenceUnitInfo [
name: keycloak-default
...]
As result the call
context.getSession().keycloakSession.getProvider(JpaConnectionProvider.class,
"default")
does return me an instance of JpaConnectionProvider Class, but the call
context.getSession().keycloakSession.getProvider(JpaConnectionProvider.class,
"mydb")
returns null.
Would you suggest possible solution of the problem?
Server Version: 3.1.0.Final
Thank a lot in advance.
7 years, 6 months
Authentication SPI and connection management
by Julian Wermes
Hello,
I've followed the instructions from
https://keycloak.gitbooks.io/documentation/server_installation/topics/dat...
But instead of changing the existing DS and provider, I added
another one, because I have to implement additional check and/or actions
against the data in the second database:
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/KeycloakDS"
pool-name="KeycloakDS" enabled="true" use-java-context="true">
...
</datasource>
<datasource jndi-name="java:jboss/datasources/myDbDS"
pool-name="mydb" enabled="true" use-java-context="true">
<connection-url>jdbc:postgresql://192.168.XX.XX/myproject</connection-url>
<driver>postgresql</driver>
<pool>
<max-pool-size>20</max-pool-size>
</pool>
<security>
<user-name>user</user-name>
<password>password</password>
</security>
</datasource>
</datasources>
</subsystem>
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
<spi name="connectionsJpa">
<provider name="default" enabled="true">
...
</provider>
<provider name="mydb" enabled="true">
<properties>
<property name="dataSource"
value="java:jboss/datasources/myDbDS"/>
<property name="initializeEmpty" value="false"/>
<property name="migrationStrategy" value="validate"/>
</properties>
</provider>
</spi>
...
</subsystem>
Now I can't find this connection provider in the admin console. Only the
default is listed in Server Info > Providers. In the log file I've found
initialization of both datasources
(MSC service thread 1-8) WFLYJCA0001: Bound data source
[java:jboss/datasources/KeycloakDS
(MSC service thread 1-1) WFLYJCA0001: Bound data source
[java:jboss/datasources/myDbDS
but only one PersistenceUnit was processed:
HHH000204: Processing PersistenceUnitInfo [
name: keycloak-default
...]
As result the call
context.getSession().keycloakSession.getProvider(JpaConnectionProvider.class,
"default")
does return me an instance of JpaConnectionProvider Class, but the call
context.getSession().keycloakSession.getProvider(JpaConnectionProvider.class,
"mydb")
returns null.
Would you suggest possible solution of the problem?
Server Version: 3.1.0.Final
Thank a lot in advance.
--
View this message in context: http://keycloak-user.88327.x6.nabble.com/keycloak-user-Authentication-SPI...
Sent from the keycloak-user mailing list archive at Nabble.com.
7 years, 6 months
Behavior of back-channel logout for starter application
by José Eduardo Paiva Dâmaso
Hello,
We are observing an issue with the back-channel logout functionality on our clustered application.
The application is clustered on 2 nodes and exposed via an Apache based load balancer (the load balancer URL is configured as Admin URL in Keycloak).
The issue is as follows:
· The user logs in to the application and starts an HTTP session on node 2
· The user logs out (HttpServletRequest.logout)
· Keycloak starts the single-log-out process and sends a ‘k_logout’ POST to our cluster
· The ‘k_logout’ POST is served by node 1, which seems to become deadlocked when trying to invalidate the clustered session (probably because it’s owned by node 2)
· The ‘k_logout’ request is aborted by our load balancer (2 minute timeout) and we have an exception on node 1:
o 19:11:08,118 WARN [org.jboss.as.clustering.web.infinispan] (JBossWeb-threads - 38) JBAS010322: Failed to load session 2Jd1GWNi9IITsG-1F37d9VLa: java.lang.IllegalStateException: AtomicMap stored under key 2Jd1GWNi9IITsG-1F37d9VLa has been concurrently removed
My question is why is Keycloak trying to back-channel logout the same client application that started the login process?
Is this the intended behavior, or do we have some wrong configuration?
Our application is mostly standard Java EE deployed on JBoss EAP 6.4 and uses keycloak-adapter 2.5.1.
Our Keycloak server is version 2.5.0.
Thanks,
José Dâmaso
7 years, 6 months
Brokering tenant SSO (instead of social SSO)
by Peter K. Boucher
We have an app that is multi-tenanted (the app is provisioned in a realm per
tenant, with some code that knows which keycloak.json to load for the
appropriate realm).
We want to support SSO from the tenants using SAML. Ideally, the tenant's
user would be logged into their own intranet, and from there, they would
click on a link and end up logged into our app without having to see any
login page or SSO provider selection page.
We were thinking that one way this could be done would be to shortcut steps
3 and 4 in the diagram at
https://keycloak.gitbooks.io/documentation/server_admin/topics/identity-brok
er/overview.html (maybe by writing javascript code in the in the page to
automatically select the tenant appropriate for the current realm and submit
it in order carry out the rest of the SSO without asking the user to click
on anything).
Is there a way to do this without kludging javascript into the SSO provider
selection page?
Thanks!
Regards,
Peter K. Boucher
7 years, 6 months
Supporting forceAuthn on a per scenario basis
by John D. Ament
Hi,
I have a use case where I need to support the SAML forceAuthn on a per
scenario basis. E.g. when a user does action 1, need to send the
forceAuthn flag, but when they do any other action don't send it.
When I look at the code in SAMLIdentityProvider, I see this being built:
SAML2AuthnRequestBuilder authnRequestBuilder = new
SAML2AuthnRequestBuilder()
.assertionConsumerUrl(assertionConsumerServiceUrl)
.destination(destinationUrl)
.issuer(issuerURL)
.forceAuthn(getConfig().isForceAuthn())
.protocolBinding(protocolBinding)
.nameIdPolicy(SAML2NameIDPolicyBuilder.format(nameIDPolicyFormat));
so it always looks at the config. If we wanted to support a forceAuthn
behavior based on other actions, how could that work? I was thinking the
oidc prompt attribute could be used, but I don't seem to have the OIDC
request available in this class.
John
7 years, 6 months