Details

    • Type: Contribution
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 3.2 SP1
    • Component/s: Repository
    • Security Level: external (External user)
    • Labels:
      None

      Description

      When authenticating against LDAP, not always all users are in the same sub-tree of ldap, so it is necesary to support authentication against multiple branches of ldap.

      For example, there can be users who can authenticate using the cn=%s,ou=myCity,ou=myState,o=myCompany but others can authenticate using the cn=%s,ou=ANOTHERCity,ou=myState,o=myCompany

      In this case, the org.alfresco.repo.security.authentication.ldap.LDAPAuthenticationComponentImpl has its limitations to log users in both LDAP sub-trees.

      I think it's necesary to have another AuthenticationComponent implementation, who allows authentication agains different LDAP sub-trees, for example, searching the user DN and then authenticate using this DN.

      I have developed this, and I suggest that you incorporate this into the Alfresco product.

      First of all, I think it would be good if we make the following changes to the org.alfresco.repo.security.authentication.ldap.LDAPAuthenticationComponentImpl component, so it can be extensible at the time of building the user DN to authenticate.
      1. Add a method called getUserDN who gets the user dn; in this case, this method only does the String.format(userNameFormat, new Object[]{userName})
      public String getUserDN(String userName) throws AuthenticationException {
      return String.format(userNameFormat, new Object[]{userName});
      }
      2. Change the authenticate(String userName, char[] password) method to use the new getUserDN when getting the ctx
          public void authenticate(String userName, char[] password) throws AuthenticationException
          {
              ...
                  ctx = ldapInitialContextFactory.getInitialDirContext(getUserDN(userName), new String(password));
              ...
          }
      3. Expose the LDAPInitialDirContextFactory, so it can be used by sub-classes
      protected LDAPInitialDirContextFactory getLDAPInitialDirContextFactory() {
      return ldapInitialContextFactory;
      }


      Now, we can make any implementations we want, and just override the getUserDN method to get the user dn as we want. The following implementation performs an ldap search given a searchBase (for example, o=myCompany if we want to search all users in myCompany) and a personQuery (for example (cn=%s) if the login is in the cn LDAP field.

      package org.alfresco.repo.security.authentication.ldap;

      import javax.naming.*;
      import javax.naming.directory.*;
      import org.apache.log4j.Logger;
      import org.alfresco.repo.security.authentication.AuthenticationException;
      import org.alfresco.repo.security.authentication.ldap.LDAPAuthenticationComponentImpl;

      public class LDAPSearchAuthenticationComponentImpl extends LDAPAuthenticationComponentImpl {
      private static Logger logger = Logger.getLogger(
      LDAPSearchAuthenticationComponentImpl.class.getName());
              /**
                * Search in sub-tree
                */
      private static SearchControls userSearchCtls;
      static {
      userSearchCtls = new SearchControls();
      userSearchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
      userSearchCtls.setCountLimit(1);
      }

      private String searchBase;
      private String personQuery;

      public LDAPSearchAuthenticationComponentImpl() {
      super();
      }

      public void setSearchBase(String searchBase) {
      this.searchBase = searchBase;
      }

      public void setPersonQuery(String personQuery) {
      this.personQuery = personQuery;
      }

      @Override
      protected String getUserDN(String userName) throws AuthenticationException {
      InitialDirContext ctx = null;
      String ret = null;
      try {
      ctx = getLDAPInitialDirContextFactory().getDefaultIntialDirContext();

      NamingEnumeration<SearchResult> searchResults = ctx.search(
      searchBase, String.format(personQuery, new Object[] { userName }),
      userSearchCtls);
      if (searchResults.hasMoreElements()) {
      SearchResult result = searchResults.next();
      ret = result.getNameInNamespace();
      }
      } catch (NamingException nx) {
      throw new AuthenticationException("User " + userName
      + " not found.", nx);
      } finally {
      if (ctx != null) {
      try {
      ctx.close();
      } catch (NamingException e) {
      }
      }
      }
      if (ret == null) {
      throw new AuthenticationException("User " + userName
      + " not found.");
      }
      return ret;
      }
      }

      And now we can use this new authentication component... change the ldap-authentication-context.xml in alfresco/extension using the new authenticationComponent, as follows

          <bean id="authenticationComponent" class="org.alfresco.repo.security.authentication.ldap.LDAPSearchAuthenticationComponentImpl">
              <property name="personService">
      <ref bean="personService"/>
      </property>
      <property name="nodeService">
      <ref bean="nodeService"/>
      </property>
              <property name="LDAPInitialDirContextFactory">
                  <ref bean="ldapInitialDirContextFactory"/>
              </property>
              <property name="allowGuestLogin">
                  <value>false</value>
              </property>

              <property name="searchBase">
                  <value>dc=myCompany</value>
              </property>
              <property name="personQuery">
                  <value><![CDATA[(cn=%s)]]></value>
              </property>
          </bean>


        Attachments

          Structure

            Activity

              People

              • Assignee:
                closedissues Closed Issues
                Reporter:
                jzulu2000 Juan David Zuluaga Arboleda (Inactive)
              • Votes:
                5 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - 2 hours
                  2h
                  Remaining:
                  Remaining Estimate - 2 hours
                  2h
                  Logged:
                  Time Spent - Not Specified
                  Not Specified

                    Structure Helper Panel