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

LDAP to Keycloak attribute mapping cannot handle arrays

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: 1.3.1.Final
    • Fix Version/s: 1.4.0.Final
    • Component/s: User Federation
    • Labels:
      None
    • Environment:

      Not relevant

    • Steps to Reproduce:
      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.

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  mposolda Marek Posolda
                  Reporter:
                  kevin_thorpe Kevin Thorpe
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  2 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: