Hello memebers,
I am trying to let a user access the grommunio WebApp by using a seperate keycloak instance with the goal to provide a Single Sign On through keycloak for different web resources of which grommunio is one.
My approach so far was following this post:
https://community.grommunio.com/d/1314-keycloak-webapp
Also, I am not sure what type of user federation I should use in keycloak. If I use an LDAP (which should be the ground truth for my SSO anyway), I get to the point were the user is successfully redirected from the WebApp to keycloak and can authenticate successfully. But once keycloak wants to redirect the user back to the webapp, I get an CODE_TO_TOKEN_ERROR:
2023-12-19 15:54:30,400 WARN [org.keycloak.events] (executor-thread-50) type=CODE_TO_TOKEN_ERROR, realmId=273eba86-63f4-4270-9b07-bf7de80ce643, clientId=gromtest-02, userId=null, ipAddress=xxx.xxx.xxx.xxx, error=invalid_client_credentials, grant_type=authorization_code
interestingly, the userId is null here. But when I fail the login, for example through entering a wrong password, the userId is not null:
2023-12-19 17:43:22,183 WARN [org.keycloak.events] (executor-thread-85) type=LOGIN_ERROR, realmId=273eba86-63f4-4270-9b07-bf7de80ce643, clientId=gromtest-02, userId=043d82bb-0eee-40ad-852f-083962cda918, ipAddress=xxx.xxx.xxx.xxx, error=invalid_user_credentials, auth_method=openid-connect, auth_type=code, redirect_uri=https://gromtest-02.de/web, code_id=7ee34959-c1ce-46bb-90b6-8d4d2fcce945
I am also not sure whether I even can even use an LDAP as user federation for logging into grommunio WebApp, or the only way is to then use grommunio as the user store. From the information I gathered, this can be achieved by installing the grommunio provider in keycloak found here: https://github.com/grommunio/keycloak-provider.
After doing this, I get an 'unexpected error' in the browser and the following error message in the logs right after trying to login with the username 'customUserName' after being redirected to keycloak (before entering any password):
`2023-12-19 17:52:55,879 INFO [org.grommunio.keycloak.storage.user.GrommunioUserStorageProvider] (executor-thread-96) getUserByUsername(customUserName)
2023-12-19 17:52:55,879 WARN [org.keycloak.services] (executor-thread-96) KC-SERVICES0013: Failed authentication: java.lang.RuntimeException: Could not load grommunio.properties file.
at org.grommunio.keycloak.storage.user.DbUtil.getConnection(DbUtil.java:22)
at org.grommunio.keycloak.storage.user.GrommunioUserStorageProvider.getUserByUsername(GrommunioUserStorageProvider.java:86)
at org.keycloak.storage.UserStorageManager.lambda$getUserByUsername$19(UserStorageManager.java:383)
at org.keycloak.utils.ServicesUtils.lambda$timeBoundOne$1(ServicesUtils.java:83)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:400)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:528)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
at org.keycloak.storage.UserStorageManager.getUserByUsername(UserStorageManager.java:383)
at org.keycloak.models.cache.infinispan.UserCacheSession.getUserByUsername(UserCacheSession.java:269)
at org.keycloak.models.utils.KeycloakModelUtils.findUserByNameOrEmail(KeycloakModelUtils.java:251)
at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.getUserFromForm(AbstractUsernameFormAuthenticator.java:188)
at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.getUser(AbstractUsernameFormAuthenticator.java:167)
at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validateUser(AbstractUsernameFormAuthenticator.java:154)
at org.keycloak.authentication.authenticators.browser.UsernameForm.validateForm(UsernameForm.java:49)
at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.action(UsernamePasswordForm.java:48)
at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:154)
at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:986)
at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:378)
at org.keycloak.services.resources.LoginActionsService.processAuthentication(LoginActionsService.java:349)
at org.keycloak.services.resources.LoginActionsService.authenticateInternal(LoginActionsService.java:341)
at org.keycloak.services.resources.LoginActionsService.authenticate(LoginActionsService.java:322)
at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:406)
at jdk.internal.reflect.GeneratedMethodAccessor483.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:154)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:118)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:560)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:452)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:413)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:321)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:415)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:378)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:174)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:131)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:33)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:429)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:240)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:154)
at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:321)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:157)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:229)
at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:82)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:147)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:84)
at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:44)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$1.handle(HttpServerCommonHandlers.java:58)
at io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers$1.handle(HttpServerCommonHandlers.java:36)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
at org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter.lambda$createBlockingHandler$0(QuarkusRequestFilter.java:82)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
2023-12-19 17:52:55,885 WARN [org.keycloak.events] (executor-thread-96) type=LOGIN_ERROR, realmId=273eba86-63f4-4270-9b07-bf7de80ce643, clientId=gromtest-02, userId=null, ipAddress=xxx.xxx.xxx.xxx, error=invalid_user_credentials, auth_method=openid-connect, auth_type=code, redirect_uri=https://gromtest-02.de/web, code_id=2ef1bcc4-823e-454b-8672-8ac63ec0c060, username=customUserName
2023-12-19 17:52:55,891 INFO [org.grommunio.keycloak.storage.user.GrommunioUserStorageProvider] (executor-thread-96) close()`
Could anybody give me a hint how to either fix my WebApp login via the LDAP as the user federation or fix the grommunio keycloak provider to use grommunio itself as the user federation?
Thank you in advance.
-rk