Uploaded image for project: 'Keycloak'
  1. Keycloak
  2. KEYCLOAK-1487

LDAP to Keycloak attribute mapping cannot handle arrays

    XMLWordPrintable

Details

    • Hide

      Create a new LDAP user. Add an attribute more than once. eg applications=keycloak and applications=website. Create a federation attribute mapper to map this attribute into Keycloak. On federation sync you get the following error trace which indicates that a tree (multi-attribute) cannot be cast to a string.

      2015-06-19 15:14:30,878 INFO [org.keycloak.federation.ldap.LDAPFederationProviderFactory] (default task-6) Sync all users from LDAP to local store: realm: master, federation provider: PI ordinary users
      2015-06-19 15:14:31,124 ERROR [io.undertow.request] (default task-6) UT005023: Exception handling request to /auth/admin/realms/master/user-federation/instances/141db483-1f5c-412f-acbb-0ea642015798/sync: java.lang.RuntimeException: request path: /auth/admin/realms/master/user-federation/instances/141db483-1f5c-412f-acbb-0ea642015798/sync
      at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:54)
      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
      at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
      at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
      at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
      at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
      at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
      at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
      at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
      at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72)
      at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
      at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:274)
      at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:253)
      at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:80)
      at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:172)
      at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199)
      at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:774)
      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)
      Caused by: org.jboss.resteasy.spi.UnhandledException: java.lang.ClassCastException: java.util.TreeSet cannot be cast to java.lang.String
      at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76)
      at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212)
      at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:149)
      at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:372)
      at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)
      at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
      at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
      at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
      at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86)
      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130)
      at org.keycloak.services.filters.ClientConnectionFilter.doFilter(ClientConnectionFilter.java:41)
      at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
      at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
      at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:40)
      ... 29 more
      Caused by: java.lang.ClassCastException: java.util.TreeSet cannot be cast to java.lang.String
      at org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapper.onImportUserFromLDAP(UserAttributeLDAPFederationMapper.java:60)
      at org.keycloak.federation.ldap.LDAPFederationProvider.importLDAPUsers(LDAPFederationProvider.java:404)
      at org.keycloak.federation.ldap.LDAPFederationProviderFactory.importLdapUsers(LDAPFederationProviderFactory.java:269)
      at org.keycloak.federation.ldap.LDAPFederationProviderFactory$1.run(LDAPFederationProviderFactory.java:223)
      at org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction(KeycloakModelUtils.java:241)
      at org.keycloak.federation.ldap.LDAPFederationProviderFactory.syncImpl(LDAPFederationProviderFactory.java:219)
      at org.keycloak.federation.ldap.LDAPFederationProviderFactory.syncAllUsers(LDAPFederationProviderFactory.java:177)
      at org.keycloak.services.managers.UsersSyncManager.syncAllUsers(UsersSyncManager.java:50)
      at org.keycloak.services.resources.admin.UserFederationProviderResource.syncUsers(UserFederationProviderResource.java:144)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137)
      at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296)
      at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250)
      at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:140)
      at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109)
      at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135)
      at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109)
      at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135)
      at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109)
      at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135)
      at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:103)
      at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356)
      ... 40 more

      Show
      Create a new LDAP user. Add an attribute more than once. eg applications=keycloak and applications=website. Create a federation attribute mapper to map this attribute into Keycloak. On federation sync you get the following error trace which indicates that a tree (multi-attribute) cannot be cast to a string. 2015-06-19 15:14:30,878 INFO [org.keycloak.federation.ldap.LDAPFederationProviderFactory] (default task-6) Sync all users from LDAP to local store: realm: master, federation provider: PI ordinary users 2015-06-19 15:14:31,124 ERROR [io.undertow.request] (default task-6) UT005023: Exception handling request to /auth/admin/realms/master/user-federation/instances/141db483-1f5c-412f-acbb-0ea642015798/sync: java.lang.RuntimeException: request path: /auth/admin/realms/master/user-federation/instances/141db483-1f5c-412f-acbb-0ea642015798/sync at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:54) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:274) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:253) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:80) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:172) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:774) 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) Caused by: org.jboss.resteasy.spi.UnhandledException: java.lang.ClassCastException: java.util.TreeSet cannot be cast to java.lang.String at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76) at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212) at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:149) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:372) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179) at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130) at org.keycloak.services.filters.ClientConnectionFilter.doFilter(ClientConnectionFilter.java:41) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:40) ... 29 more Caused by: java.lang.ClassCastException: java.util.TreeSet cannot be cast to java.lang.String at org.keycloak.federation.ldap.mappers.UserAttributeLDAPFederationMapper.onImportUserFromLDAP(UserAttributeLDAPFederationMapper.java:60) at org.keycloak.federation.ldap.LDAPFederationProvider.importLDAPUsers(LDAPFederationProvider.java:404) at org.keycloak.federation.ldap.LDAPFederationProviderFactory.importLdapUsers(LDAPFederationProviderFactory.java:269) at org.keycloak.federation.ldap.LDAPFederationProviderFactory$1.run(LDAPFederationProviderFactory.java:223) at org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction(KeycloakModelUtils.java:241) at org.keycloak.federation.ldap.LDAPFederationProviderFactory.syncImpl(LDAPFederationProviderFactory.java:219) at org.keycloak.federation.ldap.LDAPFederationProviderFactory.syncAllUsers(LDAPFederationProviderFactory.java:177) at org.keycloak.services.managers.UsersSyncManager.syncAllUsers(UsersSyncManager.java:50) at org.keycloak.services.resources.admin.UserFederationProviderResource.syncUsers(UserFederationProviderResource.java:144) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:140) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:109) at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:135) at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:103) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356) ... 40 more

    Description

      The new feature to map LDAP attributes to Keycloak user attributes cannot handle the case where an attribute appears more than once. In my example the attribute is 'applications' which appears once for each of our applications a user is allowed to access. Single entry attributes work just fine but if you map an attribute that appears more than once you get errors on synchronisation.

      Attachments

        Issue Links

          Activity

            Public project attachment banner

              context keys: [headless, issue, helper, isAsynchronousRequest, project, action, user]
              current Project key: KEYCLOAK

              People

                mposolda@redhat.com Marek Posolda
                kevin_thorpe Kevin Thorpe (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: