[keycloak-user] Having trouble with LDAP attribute mapping in 1.3.1
Marek Posolda
mposolda at redhat.com
Fri Jun 19 10:22:17 EDT 2015
Ouch, this is a bug:-(
Feel free to create JIRA.
The UserModel in Keycloak DB has each attribute modelled as one string
value. But I think I can address it with the usage of some delimiter and
then for access token has the protocol mapper, which will handle it.
So for example if your LDAP user has 3 values of attribute
"applications" with values "finance", "sales", "development", the
attribute on the Keycloak UserModel will have value like
"finance###sales###development" (The sequence ### will be used as
delimiter), but for the access token it will be divided again. So in
your application, you will have possibility to have something like:
Set<String> applications =
accessToken.getOtherClaims().getAttribute("applications");
which will return set with 3 values "finance", "sales", "development".
Marek
On 19.6.2015 15:22, Kevin Thorpe wrote:
> Ok, I think I understand. I tried 'sync all users' and got an error.
> Is this because applications is a multiple
> attribute? Obviously I will probably have access to more than one
> application. In the meantime I'll try a brand
> new user and see if that works.
>
> Log shows:
>
> 2015-06-19 14:19:26,361 INFO
> [org.keycloak.federation.ldap.LDAPFederationProviderFactory] (default
> task-2) Sync all users from LDAP to local store: realm: master,
> federation provider: PI ordinary users
> 2015-06-19 14:19:26,611 ERROR [io.undertow.request] (default task-2)
> 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
>
>
> *Kevin Thorpe
> *
> CTO
>
> <https://www.p-i.net/> <https://twitter.com/@PI_150>
>
> www.p-i.net <http://www.p-i.net/> | @PI_150 <https://twitter.com/@PI_150>
>
> M: +44 (0)7425 160 368 | T: +44 (0)203 005 6750 | F: +44(0)207 730 2635
> 150 Buckingham Palace Road, London, SW1W 9TR, UK
>
> **
> _____________________________
>
> This email and any files transmitted with it are confidential and
> intended solely for the use of the individual or entity to whom they
> are addressed. If you have received this email in error please notify
> the system manager. This message contains confidential information and
> is intended only for the individual named. If you are not the named
> addressee you should not disseminate, distribute or copy this e-mail.
> Please notify the sender immediately by e-mail if you have received
> this e-mail by mistake and delete this e-mail from your system. If you
> are not the intended recipient you are notified that disclosing,
> copying, distributing or taking any action in reliance on the contents
> of this information is strictly prohibited.
>
> *"SAVE PAPER - THINK BEFORE YOU PRINT!" *
>
>
> On 19 June 2015 at 13:50, Marek Posolda <mposolda at redhat.com
> <mailto:mposolda at redhat.com>> wrote:
>
> Thanks for the info. Now I think I know what's going on.
>
> The issue is that currently when we import users from LDAP
> (federation in general), we sync the configured attributes to the
> Keycloak DB. But during searching, we don't sync the attributes
> from LDAP to Keycloak DB anymore. So I guess you did the steps
> like this:
> - You first authenticate as LDAP user "joe" (or search this user
> from admin console), which imported this user into Keycloak DB
> - Then you created mapper for the 'applications' attribute. But
> user 'joe' was already imported into Keycloak DB from the previous
> step, right?
>
> I believe that when you import some other user from LDAP, which is
> not yet exist in Keycloak DB, the 'applications' attribute will be
> there. For the existing user, the only possibility right now is to
> use "Synchronize all users" or "Synchronize changed users" on LDAP
> federation screen. This will update existing users into Keycloak
> DB as well, so 'joe' will be updated.
>
> Please let me know if it helps. Looks that it's something we
> should address better in Keycloak.
>
> Marek
>
>
> On 19.6.2015 11:56, Kevin Thorpe wrote:
>> I had a hunch so I added a record in USER_ATTRIBUTE for
>> applications and it is getting passed
>> in the JWT claims now. That squarely points at the ldap
>> federation part.
>>
>> *Kevin Thorpe
>> *
>> CTO
>>
>> <https://www.p-i.net/> <https://twitter.com/@PI_150>
>>
>> www.p-i.net <http://www.p-i.net/> | @PI_150
>> <https://twitter.com/@PI_150>
>>
>> M: +44 (0)7425 160 368 | T: +44 (0)203 005 6750 | F: +44(0)207
>> 730 2635
>> 150 Buckingham Palace Road, London, SW1W 9TR, UK
>>
>> **
>> _____________________________
>>
>> This email and any files transmitted with it are confidential and
>> intended solely for the use of the individual or entity to whom
>> they are addressed. If you have received this email in error
>> please notify the system manager. This message contains
>> confidential information and is intended only for the individual
>> named. If you are not the named addressee you should not
>> disseminate, distribute or copy this e-mail. Please notify the
>> sender immediately by e-mail if you have received this e-mail by
>> mistake and delete this e-mail from your system. If you are not
>> the intended recipient you are notified that disclosing, copying,
>> distributing or taking any action in reliance on the contents of
>> this information is strictly prohibited.
>>
>> *"SAVE PAPER - THINK BEFORE YOU PRINT!" *
>>
>>
>> On 19 June 2015 at 10:42, Kevin Thorpe <kevin.thorpe at p-i.net
>> <mailto:kevin.thorpe at p-i.net>> wrote:
>>
>> Hi Marek, thanks for the quick reply.
>>
>> 1. I am definitely sure that the attributes I need are in the
>> LDAP record.
>>
>> 2. adding trace to federation.ldap shows my mapped attributes
>> being read
>>
>> 3. there is no USER_ATTRIBUTES table I'm assuming you meant
>> USER_ATTRIBUTE but it doesn't have my attributes.
>> it does have a reference to my LDAP_ID so i8t looks like
>> it should be here
>>
>> MariaDB [keycloak]> select * from USER_ATTRIBUTE;
>> +---------+-------------------------------------+--------------------------------------+
>> | NAME | VALUE | USER_ID |
>> +---------+-------------------------------------+--------------------------------------+
>> | LDAP_ID | 7fc89601-96e711e2-a5a7b2a9-738d4470 |
>> 471f0b4f-cb7c-4610-b3d6-ddd3a18e9986 |
>> | LDAP_ID | 3245fc81-55c211e2-a5a7b2a9-738d4470 |
>> 6d64f5a2-d356-4ab6-9b4d-3f89a3ee38c4 |
>> +---------+-------------------------------------+--------------------------------------+
>>
>> thanks for your time on this
>>
>> *Kevin Thorpe
>> *
>> CTO
>>
>> <https://www.p-i.net/> <https://twitter.com/@PI_150>
>>
>> www.p-i.net <http://www.p-i.net/> | @PI_150
>> <https://twitter.com/@PI_150>
>>
>> M: +44 (0)7425 160 368 | T: +44 (0)203 005 6750 | F:
>> +44(0)207 730 2635
>> 150 Buckingham Palace Road, London, SW1W 9TR, UK
>>
>> **
>> _____________________________
>>
>> This email and any files transmitted with it are confidential
>> and intended solely for the use of the individual or entity
>> to whom they are addressed. If you have received this email
>> in error please notify the system manager. This message
>> contains confidential information and is intended only for
>> the individual named. If you are not the named addressee you
>> should not disseminate, distribute or copy this e-mail.
>> Please notify the sender immediately by e-mail if you have
>> received this e-mail by mistake and delete this e-mail from
>> your system. If you are not the intended recipient you are
>> notified that disclosing, copying, distributing or taking any
>> action in reliance on the contents of this information is
>> strictly prohibited.
>>
>> *"SAVE PAPER - THINK BEFORE YOU PRINT!" *
>>
>>
>> On 19 June 2015 at 10:15, Marek Posolda <mposolda at redhat.com
>> <mailto:mposolda at redhat.com>> wrote:
>>
>> There are few steps here and the result will work only if
>> all steps success. So it might help to try which step
>> could be wrong here:
>>
>> 1) You can doublecheck if your user really has
>> 'applications' attribute in LDAP
>>
>> 2) If (1) is ok, you can enable TRACE logging for
>> "org.keycloak.federation.ldap" category in standalone.xml
>> . With it, you should see some trace messages with the
>> names and values of all LDAP attributes, which are loaded
>> in user record. You should see the 'applications'
>> attribute loaded
>>
>> 3) If (2) is ok, you can browse keycloak database and
>> check if attribute 'applications' is really here. The
>> user attributes are saved in table USER_ATTRIBUTES.
>> Currently it's not possible to browse user attributes
>> generically in admin console (unless you do custom theme)
>> so browse DB seems to be the only possibility.
>>
>> 4) If (3) is ok, the issue is not in LDAP interaction,
>> but in protocol mapper configuration. Make sure you use
>> correct protocol mapper (In your case it should be "User
>> attributes" mapper, not "User property" mapper). Also if
>> your application is Java based, the value of
>> 'applications' claim is saved in accessToken in
>> 'otherClaims' map and can be retrieved with something
>> like: accessToken.getOtherClaims().get("applications");
>>
>> Marek
>>
>>
>>
>> On 18.6.2015 17:50, Kevin Thorpe wrote:
>>> Thanks to the team for 1.3.1. We were eagerly waiting
>>> for that to add LDAP attribute mappings which I see has
>>> now been done. Unfortunately I can't seem to get it to work.
>>>
>>> I have added a user attribute mapper to my ldap
>>> federation. This maps the LDAP atribute 'applications'
>>> which exists on my LDAP user record to 'applications' in
>>> Keycloak.
>>>
>>> I have also added a user attribute token mapper to my
>>> Keycloak client definition to map user attribute
>>> 'applications' to token claim 'applications'. I've also
>>> asked to add to both id and access token.
>>>
>>> However this attribute is not present in either the ID
>>> or access token when testing. Is there something I've
>>> missed?
>>>
>>> Something that may be an issue though is that I'm using
>>> a home written openid-connect Lua client based on your
>>> javascript one. This uses the endpoint
>>> /auth/realms/master/protocol/openid-connect/token. Is it
>>> that the openid-connect endpoint doesn't support these
>>> attributes yet?
>>>
>>> *Kevin Thorpe
>>> *
>>> CTO, PI ltd
>>>
>>>
>>> _______________________________________________
>>> keycloak-user mailing list
>>> keycloak-user at lists.jboss.org <mailto:keycloak-user at lists.jboss.org>
>>> https://lists.jboss.org/mailman/listinfo/keycloak-user
>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-user/attachments/20150619/e7061280/attachment-0001.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 3053 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20150619/e7061280/attachment-0004.jpe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 1204 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20150619/e7061280/attachment-0005.jpe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 3053 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20150619/e7061280/attachment-0006.jpe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/jpeg
Size: 1204 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20150619/e7061280/attachment-0007.jpe
More information about the keycloak-user
mailing list