14 Replies Latest reply on Aug 3, 2007 10:22 AM by roth

    LDAPExtUserModuleImpl and userSearchFilter

    roth Newbie

      Hi

      I setting up a portal with LDAPExtUserModuleImpl with Microsoft Active Directory. So far, everything is going along nicely. I am already able to authenticate against my AD, and I am now working on authorisation and integrating roles. I'll post my config files once everything is working.

      Now, the following small problem showed up:

      In ldap_identity-config.xml, I have

      <option>
      <name>userSearchFilter</name>
      <value>(&(sAMAccountName={0})(objectClass=User))</value>
      </option>
      


      This gives me the following error:

      --- MBeans waiting for other MBeans ---
      ObjectName: portal:service=Module,type=IdentityServiceController
       State: FAILED
       Reason: org.jboss.portal.identity.IdentityException: Cannot parse identity configuration file
      


      If I change the filter to a mere

      (sAMAccountName={0})
      


      everything works like a charm.

      Is this a bug, or am I doing something wrong with that filter?

      I am using Jboss 4.3.0 and JBoss_Portal_2_6_0 from svn.

      Thanks,
      Tobias

        • 1. Re: LDAPExtUserModuleImpl and userSearchFilter
          Boleslaw Dawidowicz Master

          Please try:

          <value><![CDATA[(&(sAMAccountName={0})(objectClass=User))]]></value>


          I would be very interested to learn if you succeeded with MSAD.

          • 2. Re: LDAPExtUserModuleImpl and userSearchFilter
            roth Newbie

            D'oh! Of course this works.

            I got my line from http://jbossportal.blogspot.com/ where there is no CDATA escaping, and of course I stopped my brain when I copied it from there. Maybe someone add that to that blog entry.

            I'll keep you updated on my progress, so far everything looks good.

            • 3. Re: LDAPExtUserModuleImpl and userSearchFilter
              Boleslaw Dawidowicz Master

              It happens to everyone time to time :)

              I updated blog post like you suggested. I think that you shouldn't have many problems with MSAD. The one I'm aware of is the password change (can be done by portal users). As far as I know MSAD requires you to use SSL connection to let you update related attribute. I haven't tested user/roles membership management with MSAD so it would be nice if you try. But as far as you don't use portal to assign roles, but rely on LDAP server tools it should be fine.

              If you succeed could you create a wiki page describing your configuration? This would be a good contribution.

              • 4. Re: LDAPExtUserModuleImpl and userSearchFilter
                roth Newbie

                I'm still on this. Both authentication and authorisation work fine now, with one small exception.

                Searching with a filter of "member=cn=LastName\, FirstName, ou=People, ..." does not work if there is a comma between LastName and FirstName. It works for filters without such a comma.

                I tried escaping the comma with a backslash, not escaping it, and I also tried with two different standalone ldap search programs. Everywhere the same, my users with commas are not found.

                For portal authorisation, this means that if a user has said comma, it is not recognised as being part of any role.

                I don't know if this is an AD-only problem or whether I am just doing something wrong here. I'm not sure what to do about it, I am still researching the matter. I'll do a wiki page once everything works.

                Thanks,
                Tobias

                • 5. Re: LDAPExtUserModuleImpl and userSearchFilter
                  roth Newbie

                  Update: With the help of OpenLdap's command line search tool 'ldapsearch',
                  which gave me more verbose error messages than the Windows Gui Tools I was using before, I was able to find the cause for my problem:

                  A filter with a single backslash for escaping the comma is not recognised as a correct filter, thus no results from my query. Double-escaping the comma (i.e. adding two backslashes instead of just one) works and yields results.

                  Now the question stands: could this be a bug in the ldap search code from the portal?

                  Thanks,
                  Tobias

                  • 6. Re: LDAPExtUserModuleImpl and userSearchFilter
                    Boleslaw Dawidowicz Master

                    So to be clear - when you use double backslash coma in ldapsearch you get correct result but this still doesn't work in portal config?

                    It may be a bug but I think that the usage of filter is as simple as passing it to the JNDI API. Could you try enabling DEBUG logging for package 'org.jboss.portal.identity.ldap' or 'org.jboss.portal.identity'. It should be verbose on the filter/context during user search.

                    If you are sure it fails, please create a JIRA issue and assign it to me.

                    • 7. Re: LDAPExtUserModuleImpl and userSearchFilter
                      roth Newbie

                       

                      So to be clear - when you use double backslash coma in ldapsearch you get correct result but this still doesn't work in portal config?


                      Yes, exactly. In the portal, LDAPExtRoleModule doesn't find any Role memberships for users with a comma in their username. If the user has no comma, it finds roles.

                      Here is an example that works, from the bundled ldap example:

                      2007-07-17 10:22:33,136 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
                      2007-07-17 10:22:33,136 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModuleImpl] findUserByUserName(): username = admin
                      2007-07-17 10:22:33,136 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModuleImpl] Search filter: (uid=admin)
                      2007-07-17 10:22:33,136 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModuleImpl] Search filter: (uid=admin)
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModule] user uid: uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModule] user dn: uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPStaticGroupMembershipModuleImpl] getRoles(): user DN = uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPStaticGroupMembershipModuleImpl] Search filter: member=uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPRoleModuleImpl] Search filter: member=uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPRoleModule] role uid: cn=Admin,ou=Roles,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPRoleModule] role dn: cn=Admin,ou=Roles,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPRoleModule] role uid: cn=User,ou=Roles,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPRoleModule] role dn: cn=User,ou=Roles,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPRoleModule] role uid: cn=foo,ou=Roles,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,152 DEBUG [org.jboss.portal.identity.ldap.LDAPRoleModule] role dn: cn=foo,ou=Roles,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:22:33,183 INFO [STDOUT] user login


                      If I change the DN of admin to 'mister\, admin' and also update the affected roles, it doesn't find roles anymore:

                      2007-07-17 10:35:52,153 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
                      2007-07-17 10:35:52,153 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModuleImpl] findUserByUserName(): username = admin
                      2007-07-17 10:35:52,153 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModuleImpl] Search filter: (uid=admin)
                      2007-07-17 10:35:52,153 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModuleImpl] Search filter: (uid=admin)
                      2007-07-17 10:35:52,216 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModule] user uid: uid=mister\, admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:35:52,216 DEBUG [org.jboss.portal.identity.ldap.LDAPUserModule] user dn: uid=mister\, admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:35:52,216 DEBUG [org.jboss.portal.identity.ldap.LDAPStaticGroupMembershipModuleImpl] getRoles(): user DN = uid=mister\, admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:35:52,216 DEBUG [org.jboss.portal.identity.ldap.LDAPStaticGroupMembershipModuleImpl] Search filter: member=uid=mister\, admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:35:52,216 DEBUG [org.jboss.portal.identity.ldap.LDAPRoleModuleImpl] Search filter: member=uid=mister\, admin,ou=People,o=test,dc=portal,dc=example,dc=com
                      2007-07-17 10:35:52,325 INFO [STDOUT] user login


                      When I copy&paste the role search filters from above into an ldap search tool, the one from the first example works, the one from the second doesn't. If I add another backslash to the second example, it works as well.

                      • 8. Re: LDAPExtUserModuleImpl and userSearchFilter
                        roth Newbie

                        I forgot: The examples I was quoting are with LDAPRoleModuleImpl, but I see the same behaviour with LDAPExtRoleModuleImpl, which I am using for my AD.

                        The examples I posted where set up after the first ldap example blog post here: http://jbossportal.blogspot.com/search/label/portal

                        • 9. Re: LDAPExtUserModuleImpl and userSearchFilter
                          roth Newbie

                          I created JBPORTAL-1592, but I couldn't assign it to you.

                          Thanks,
                          Tobias

                          • 10. Re: LDAPExtUserModuleImpl and userSearchFilter
                            Boleslaw Dawidowicz Master

                            Got it! At the moment I'm on different things but I will look at it later this week, and will let you know here.

                            Big thanks for being so proactive with this!

                            • 11. Re: LDAPExtUserModuleImpl and userSearchFilter
                              Gary Cuozzo Newbie

                              Just a note: the issue with needing 2 '\' to escape the ',' may be also be related to the shell that you ran ldapsearch in eating the 1st '\'. So, the first \ escapes the second \, which causes a \ to be sent to ldapsearch, which escapes the comma.

                              This post happened to pique my interest because I just fixed a bug in a shell script related to a similar problem and thought this may keep somebody else from losing their sanity with \'s.

                              Good luck,
                              gary.

                              • 12. Re: LDAPExtUserModuleImpl and userSearchFilter
                                Boleslaw Dawidowicz Master

                                I'm playing with this.

                                So with such ldif:

                                
                                dn: dc=example,dc=com
                                objectclass: top
                                objectclass: dcObject
                                objectclass: organization
                                dc: example
                                o: example
                                
                                dn: dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: dcObject
                                objectclass: organization
                                o: portal
                                dc: portal
                                
                                dn: o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: organization
                                o: test
                                
                                dn: ou=People,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: organizationalUnit
                                ou: People
                                
                                dn: uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: inetOrgPerson
                                objectclass: person
                                uid: admin
                                cn: Java Duke
                                sn: Duke
                                userPassword: admin
                                mail: email@email.com
                                
                                dn: uid=user,ou=People,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: inetOrgPerson
                                objectclass: person
                                uid: user
                                cn: user
                                sn: Portal User
                                userPassword: user
                                mail: email@email.com
                                
                                dn: uid=jduke\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: inetOrgPerson
                                objectclass: person
                                uid: jduke, Duke
                                cn: Java Duke
                                sn: Duke
                                userPassword: theduke
                                mail: email@email.com
                                
                                dn: uid=jduke1\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: inetOrgPerson
                                objectclass: person
                                uid: jduke1, Duke
                                cn: Java Duke1
                                sn: Duke1
                                userPassword: theduke
                                mail: email@email.com
                                
                                
                                dn: uid=jduke2\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: inetOrgPerson
                                objectclass: person
                                uid: jduke2, Duke
                                cn: Java Duke2
                                sn: Duke2
                                userPassword: theduke
                                mail: email@email.com
                                
                                dn: uid=jduke3\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: inetOrgPerson
                                objectclass: person
                                uid: jduke3, Duke
                                cn: Java Duke3
                                sn: Duke3
                                userPassword: theduke
                                mail: email@email.com
                                
                                dn: uid=jduke4\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: inetOrgPerson
                                objectclass: person
                                uid: jduke4, Duke
                                cn: Java Duke4
                                sn: Duke4
                                userPassword: theduke
                                mail: email@email.com
                                
                                dn: ou=Roles,o=test,dc=portal,dc=example,dc=com
                                objectclass: top
                                objectclass: organizationalUnit
                                ou: Roles
                                
                                dn: cn=Admin,ou=Roles,o=test,dc=portal,dc=example,dc=com
                                objectClass: top
                                objectClass: groupOfNames
                                cn: Admin
                                description: Portal admin role
                                member: uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                                
                                dn: cn=User,ou=Roles,o=test,dc=portal,dc=example,dc=com
                                objectClass: top
                                objectClass: groupOfNames
                                cn: User
                                description: Portal user role
                                member: uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=user,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke1\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke2\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke3\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke4\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                
                                dn: cn=The\, Dukes,ou=Roles,o=test,dc=portal,dc=example,dc=com
                                objectClass: top
                                objectClass: groupOfNames
                                cn: The, Dukes
                                description: Portal user role
                                member: uid=admin,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=user,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke1\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke2\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke3\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com
                                member: uid=jduke4\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com


                                Role resolution works ok. For the search filters I succeeded with such configuration:

                                <option>
                                 <name>roleSearchFilter</name>
                                 <value><![CDATA[(&(cn={0})(member=uid=jduke\\\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com))]]></value>
                                </option>
                                


                                I think that code changes are not needed here. Actually with command line I also need to use 3 backslashes like here:

                                 ldapsearch -x -h localhost -p 10389 -D"cn=Directory Manager" -w password -s sub -b "dc=example,dc=com" "(&(cn=*)(member=uid=jduke\\\, Duke,ou=People,o=test,dc=portal,dc=example,dc=com))"
                                


                                otherwise with '\\,' or '\' you have 'Bad search filter (-7)' error. So its just the way you need to escape it.

                                Anyway I found out that for UserModule.createUser() method userName need to be parsed against RFC2253 (http://ietf.org/rfc/rfc2253.txt), so this need to be corrected.

                                Could you check if it works for you in MSAD if you just use "member=cn=LastName\\\, FirstName, ou=People, ..." filter?

                                • 13. Re: LDAPExtUserModuleImpl and userSearchFilter
                                  roth Newbie

                                  Hi, sorry for coming back to this so late, I got distracted by some other work.

                                  Maybe I am misunderstanding something, but I still think there is a bug around. The filter you posted works and all, but in a real-world scenario, that's not what one would use for a filter. The filter is constructed by the code, one would not directly add LastName, FirstName for a filter, or only that specific user would be found.

                                  If you look at the log snippets I pasted in a previous post, here is what happens: The user enters his credentials in the login box. The code finds the record for that user, and from that record, it takes the DN. From that DN (which may contain a comma), it constructs the search filter to search for roles. Now, if the DN does contain a comma, no roles are found, because the code does not escape the comma correctly. There is no way I can fix this by adapting the filters in my config, or am I missing something?

                                  Thanks,
                                  Tobias