8 Replies Latest reply on Oct 29, 2009 5:20 AM by Pawel Maczka

    identities from LDAP example pls!

    Pawel Maczka Newbie

      Here is my request for an example or how-to use LDAP for identities and roles in jBPM to:
      - assign to tasks
      - authenticate in console

      And all without JBoss please!

        • 1. Re: identities from LDAP example pls!
          Ronald van Kuijk Master

          I assume you are talking about jBPM 6? are you... Or is it jBPM 2,71828183?

          • 2. Re: identities from LDAP example pls!
            Pawel Maczka Newbie

            I googled that people trying own identity systems with jBPM even 2 years ago ( example: http://jelmer.jteam.nl/2007/10/08/extensibility-jbpm-style/ ). jBPM doc mentions about it and its config files seems to be prepared to configure this. Just wandered if you have any example. I cannot synch hundreds of users and roles from in-house systems into jBPM manually. Till identities are not pluggable I understand jBPM is in early development stage. For me it is first thing to do :)

            • 3. Re: identities from LDAP example pls!
              Pawel Maczka Newbie

              Well, if your question about version was not sarcastic then I answer: 4.1

              • 4. Re: identities from LDAP example pls!
                Ronald van Kuijk Master

                In jBPM4 the identity service is much more plugable.

                A search in google resulted in https://jira.jboss.org/jira/browse/JBPM-2172

                This gives you some hints on the status, in combination with some hints on where to look at the sourcecode as an example.

                And yes, it was kind of sarcastic since you did not mention anything at all.... 4.1 is good to start with.

                • 5. Re: identities from LDAP example pls!
                  shiva0 Newbie

                  Here is the module I've coded to access a LDAP on ADS. Should get you started on what you need.

                  public class IdentitySessionImpl implements IdentitySession {
                  
                   private static IdentitySessionProperties props = null;
                  
                   public Group findGroupById(String iGroupId) {
                   Timer lTimer = Timer.getInstance(getClass(), "findGroupById");
                   InitialDirContext lContext = null;
                   GroupImpl lGroup = null;
                  
                   try
                   {
                   lContext = getLDAPContext();
                  
                   // Set up Search Controls
                   SearchControls lSearchControls = new SearchControls();
                   lSearchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
                  
                   // set time limit for query. Useful for preventing the application from being blocked
                   lSearchControls.setTimeLimit( 3000 );
                   lSearchControls.setReturningObjFlag( true );
                  
                   // set filter
                   String lSearchString = "(&(cn=" + iGroupId + ")(objectclass=group))";
                  
                   // perform search on directory
                   NamingEnumeration<SearchResult> lResults = lContext.search( getProps().getLdapBase(), lSearchString, lSearchControls );
                  
                   if ( lResults.hasMore() )
                   lGroup = getGroup(lResults.next());
                   }
                   catch (Throwable e)
                   {
                   throw new RuntimeException(e);
                   }
                   finally
                   {
                   lTimer.log();
                   try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                   }
                  
                   return lGroup;
                   }
                  
                   public List<Group> findGroupsByUser(String iUserId) {
                   Timer lTimer = Timer.getInstance(getClass(), "findGroupsByUser");
                   InitialDirContext lContext = null;
                   List<Group> lGroups = null;
                  
                   try
                   {
                   lContext = getLDAPContext();
                  
                   // Set up Search Controls
                   SearchControls lSearchControls = new SearchControls();
                   lSearchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
                  
                   // set time limit for query. Useful for preventing the application from being blocked
                   lSearchControls.setTimeLimit( 3000 );
                   lSearchControls.setReturningObjFlag( true );
                  
                   // set filter
                   String lSearchString = "(&(|(cn=" + iUserId + ")(samAccountName=" + iUserId + "))(objectclass=user))";
                  
                   // perform search on directory
                   NamingEnumeration<SearchResult> lResults = lContext.search( getProps().getLdapBase(), lSearchString, lSearchControls );
                  
                   if ( lResults.hasMore() )
                   lGroups = getGroups(lResults.next());
                   }
                   catch (Throwable e)
                   {
                   throw new RuntimeException(e);
                   }
                   finally
                   {
                   lTimer.log();
                   try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                   }
                  
                   return lGroups;
                   }
                  
                   public List<Group> findGroupsByUserAndGroupType(String iUserId, String iGroupType) {
                   return findGroupsByUser(iUserId);
                   }
                  
                   public User findUserById(String iUserId) {
                   Timer lTimer = Timer.getInstance(getClass(), "findUserById");
                   InitialDirContext lContext = null;
                   UserImpl lUser = null;
                  
                   try
                   {
                   lContext = getLDAPContext();
                  
                   // Set up Search Controls
                   SearchControls lSearchControls = new SearchControls();
                   lSearchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
                  
                   // set time limit for query. Useful for preventing the application from being blocked
                   lSearchControls.setTimeLimit( 3000 );
                   lSearchControls.setReturningObjFlag( true );
                  
                   // set filter
                   String lSearchString = "(&(|(cn=" + iUserId + ")(samAccountName=" + iUserId + "))(objectclass=user))";
                  
                   // perform search on directory
                   NamingEnumeration<SearchResult> lResults = lContext.search( getProps().getLdapBase(), lSearchString, lSearchControls );
                  
                   if ( lResults.hasMore() )
                   lUser = getUser(lResults.next());
                   }
                   catch (Throwable e)
                   {
                   throw new RuntimeException(e);
                   }
                   finally
                   {
                   lTimer.log();
                   try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                   }
                  
                   return lUser;
                   }
                  
                   public List<User> findUsers() {
                   Timer lTimer = Timer.getInstance(getClass(), "findUsers");
                   List<User> lUsers = new ArrayList<User>();
                   InitialDirContext lContext = null;
                  
                   try
                   {
                   lContext = getLDAPContext();
                  
                   // Set up Search Controls
                   SearchControls lSearchControls = new SearchControls();
                   lSearchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
                  
                   // set time limit for query. Useful for preventing the application from being blocked
                   lSearchControls.setTimeLimit( 3000 );
                   lSearchControls.setReturningObjFlag( true );
                  
                   // set filter
                   String lSearchString = "(&(objectclass=user))";
                  
                   // perform search on directory
                   NamingEnumeration<SearchResult> lResults = lContext.search( getProps().getLdapBase(), lSearchString, lSearchControls );
                  
                   while ( lResults.hasMore() )
                   lUsers.add( getUser(lResults.next()) );
                   }
                   catch (Throwable e)
                   {
                   throw new RuntimeException(e);
                   }
                   finally
                   {
                   lTimer.log();
                   try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                   }
                  
                   return lUsers;
                   }
                  
                   public List<User> findUsersByGroup(String iGroup) {
                   Timer lTimer = Timer.getInstance(getClass(), "findUsersByGroup");
                   List<User> lUsers = new ArrayList<User>();
                   InitialDirContext lContext = null;
                  
                   try
                   {
                   lContext = getLDAPContext();
                  
                   // Set up Search Controls
                   SearchControls lSearchControls = new SearchControls();
                   lSearchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
                  
                   // set time limit for query. Useful for preventing the application from being blocked
                   lSearchControls.setTimeLimit( 3000 );
                   lSearchControls.setReturningObjFlag( true );
                  
                   // set filter
                   String lSearchString = "(&(memberof=CN=" + iGroup + ",CN=Users," + getProps().getLdapBase() + ")(objectclass=user))";
                  
                   // perform search on directory
                   NamingEnumeration<SearchResult> lResults = lContext.search( getProps().getLdapBase(), lSearchString, lSearchControls );
                  
                   while ( lResults.hasMore() )
                   {
                   lUsers.add( getUser(lResults.next()) );
                   }
                   }
                   catch (Throwable e)
                   {
                   throw new RuntimeException(e);
                   }
                   finally
                   {
                   lTimer.log();
                   try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                   }
                  
                   return lUsers;
                   }
                  
                   public List<User> findUsersById(String... iUserIds) {
                   Timer lTimer = Timer.getInstance(getClass(), "findUsersById");
                   List<User> lUsers = new ArrayList<User>(iUserIds.length);
                  
                   try
                   {
                   for (String lUserId : iUserIds) {
                   lUsers.add( findUserById(lUserId) );
                   }
                   }
                   finally
                   {
                   lTimer.log();
                   }
                  
                   return lUsers;
                   }
                  
                   private UserImpl getUser(SearchResult iResult) throws NamingException, IOException {
                   final String iUserId = getAttributeValue(iResult, getProps().getUserIdAttr());
                   final String lEmail = getAttributeValue(iResult, getProps().getUserEmailAttr());
                   final String lFirstname = getAttributeValue(iResult, getProps().getUserFirstNameAttr());
                   final String lLastname = getAttributeValue(iResult, getProps().getUserLastNameAttr());
                  
                   final UserImpl lUser = new UserImpl(iUserId, lFirstname, lLastname);
                   lUser.setBusinessEmail(lEmail + "@DUMMY.gc.ca");
                  
                   return lUser;
                   }
                  
                   private GroupImpl getGroup(SearchResult iResult) throws NamingException, IOException {
                   final String iGroupId = getAttributeValue(iResult, getProps().getGroupIdAttr());
                  
                   final GroupImpl lGroup = new GroupImpl(iGroupId);
                  
                   return lGroup;
                   }
                  
                   private List<Group> getGroups(SearchResult iResult) throws NamingException, IOException {
                   NamingEnumeration<?> lAllAttrValues = null;
                  
                   final List<Group> lGroups = new ArrayList<Group>();
                   final Attribute lAttr = iResult.getAttributes().get(getProps().getMemberOfAttr());
                  
                   if ( lAttr != null )
                   lAllAttrValues = lAttr.getAll();
                  
                   while ( lAllAttrValues.hasMore() )
                   {
                   String lGroupDN = (String) lAllAttrValues.next();
                   lGroups.add(new GroupImpl(getExtractedIdFromDN(lGroupDN)));
                   }
                  
                   return lGroups;
                   }
                  
                   /**
                   * Remove the DN information and extract on the group CN (id)
                   * CN=BPE-Management,CN=Users,DC=portaildev,DC=,DC=gc,DC=ca becomes BPE-Management
                   * @param iGroupDN
                   * @return
                   */
                   private String getExtractedIdFromDN(String iGroupDN) {
                   StringTokenizer lTok = new StringTokenizer(iGroupDN, ",");
                  
                   String lGroupCN = lTok.nextToken();
                  
                   return lGroupCN.substring(3);
                   }
                  
                   private String getAttributeValue(SearchResult iResult, String iAttributeName) throws NamingException {
                   NamingEnumeration<?> lAllAttrValues = null;
                   Attribute lAttr = iResult.getAttributes().get(iAttributeName);
                  
                   if ( lAttr != null )
                   lAllAttrValues = lAttr.getAll();
                  
                   if ( lAllAttrValues != null && lAllAttrValues.hasMore() )
                   return (String) lAllAttrValues.next();
                   else
                   return null;
                   }
                  
                   /**
                   * Fetch the LDAP Initial Context
                   *
                   * @return The InitialDirContext
                   *
                   * @throws NamingException
                   * @throws IOException
                   */
                   private InitialDirContext getLDAPContext() throws NamingException, IOException {
                   InitialDirContext lLdapCtx = null;
                  
                   // Set up LDAP configuration settings
                   Hashtable<String, String> lContextValues = new Hashtable<String, String>();
                  
                   lContextValues.put("java.naming.ldap.version", "3");
                   lContextValues.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
                   lContextValues.put("java.naming.security.authentication", "Simple");
                   lContextValues.put("java.naming.referral", "follow");
                   lContextValues.put("java.naming.provider.url", getProps().getLdapUrl());
                   lContextValues.put("java.naming.security.principal", getProps().getLdapProvider());
                   lContextValues.put("java.naming.security.credentials", getProps().getLdapCredentials());
                  
                   // Make LDAP connection
                   lLdapCtx = new InitialDirContext(lContextValues);
                  
                   return lLdapCtx;
                   }
                  
                   private static IdentitySessionProperties getProps() throws IOException
                   {
                   if ( props == null )
                   {
                   props = new IdentitySessionProperties();
                   }
                  
                   return props;
                   }
                  
                   /* The following methods won't be implemented */
                   public String createGroup(String arg0, String arg1, String arg2) {
                   throw new UnsupportedOperationException();
                   }
                  
                   public void createMembership(String arg0, String arg1, String arg2) {
                   throw new UnsupportedOperationException();
                   }
                  
                   public String createUser(String arg0, String arg1, String arg2, String arg3) {
                   throw new UnsupportedOperationException();
                   }
                  
                   public void deleteGroup(String arg0) {
                   throw new UnsupportedOperationException();
                   }
                  
                   public void deleteMembership(String arg0, String arg1, String arg2) {
                   throw new UnsupportedOperationException();
                   }
                  
                   public void deleteUser(String arg0) {
                   throw new UnsupportedOperationException();
                   }
                  }
                  


                  • 6. Re: identities from LDAP example pls!
                    Sebastian Schneider Master

                    Hello shiva, hello everybody

                    thanks for posting this code. What do you and the developers think about taking this as a base to develop an out-of-the-box LDAP-integration? Of course there will be an integration of JBoss in the future and thus LDAP-support via IDM. But would be nice for people who do not want to use IDM.

                    Let me know what you think.

                    • 8. Re: identities from LDAP example pls!
                      Pawel Maczka Newbie

                      Thank you very much shiva0. I have managed to test it in my environment. I have modified your code for two important reasons:

                      - all strings and especially search strings are moved to properties file now. This allows to change search strings for different directories: MS Active Directory , IBM Lotus Domino, etc.
                      - I have changed the way it search for user groups - it is now looking for members in group record instead of looking for memberOf's in user record. I think it is better attampt and the only possible for IBM Lotus Domino

                      Below is jbpm.cfg.xml that I am still not sure if it is ok for pluged IdentitySession

                      <?xml version="1.0" encoding="UTF-8"?>
                      <jbpm-configuration>
                       <import resource="jbpm.default.cfg.xml" />
                       <import resource="jbpm.tx.hibernate.cfg.xml" />
                       <import resource="jbpm.jpdl.cfg.xml" />
                      <!-- <import resource="jbpm.identity.cfg.xml" /> -->
                       <process-engine-context>
                       <identity-service/>
                       </process-engine-context>
                       <transaction-context>
                       <object class="sam.IdentitySessionImpl" />
                       </transaction-context>
                      </jbpm-configuration>
                      


                      Now the class and then ldap.properties for MS Active Directory and IBM Lotus Domino. I have both of them so parameters are TESTED:

                      package sam;
                      
                      import java.io.FileInputStream;
                      import java.io.IOException;
                      import java.util.List;
                      import java.util.ArrayList;
                      import java.util.Hashtable;
                      import java.util.StringTokenizer;
                      import java.util.Properties;
                      
                      import javax.naming.*;
                      import javax.naming.directory.*;
                      
                      import org.apache.commons.logging.Log;
                      import org.apache.commons.logging.LogFactory;
                      
                      import org.jbpm.api.identity.Group;
                      import org.jbpm.api.identity.User;
                      import org.jbpm.pvm.internal.identity.impl.GroupImpl;
                      import org.jbpm.pvm.internal.identity.impl.UserImpl;
                      import org.jbpm.pvm.internal.identity.spi.IdentitySession;
                      
                      
                      public class IdentitySessionImpl implements IdentitySession {
                      
                       private Log log = LogFactory.getLog(getClass());
                       private static Properties props = null;
                       private SearchControls lSearchControls = null;
                      
                       public IdentitySessionImpl() {
                      
                       lSearchControls = new SearchControls();
                       lSearchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
                       // set time limit for query. Useful for preventing the application from being blocked
                       try{
                       lSearchControls.setTimeLimit( new Integer(getProps().getProperty("timeout")).intValue() );
                       }
                       catch (Throwable e)
                       {
                       throw new RuntimeException(e);
                       }
                       lSearchControls.setReturningObjFlag( true );
                       }
                      
                       public Group findGroupById(String iGroupId) {
                      
                       InitialDirContext lContext = null;
                       GroupImpl lGroup = null;
                      
                       try
                       {
                       lContext = getLDAPContext();
                      
                       NamingEnumeration<SearchResult> lResults = lContext.search(
                       getProps().getProperty("roleBase"),
                       getProps().getProperty("findGroupByIdSearch"),
                       new Object[]{ iGroupId },
                       lSearchControls );
                      
                       if ( lResults.hasMore() )
                       lGroup = getGroup(lResults.next());
                       }
                       catch (Throwable e)
                       {
                       throw new RuntimeException(e);
                       }
                       finally
                       {
                       try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                       }
                      
                       return lGroup;
                       }
                      
                       public List<Group> findGroupsByUser(String iUserId) {
                      
                       InitialDirContext lContext = null;
                       List<Group> lGroups = new ArrayList<Group>();
                      
                       try
                       {
                       lContext = getLDAPContext();
                      
                       NamingEnumeration<SearchResult> lResults = lContext.search(
                       getProps().getProperty("roleBase"),
                       getProps().getProperty("findGroupsByUserSearch"),
                       new Object[]{ findUserById(iUserId).toString() },
                       lSearchControls );
                      
                       while ( lResults.hasMore() )
                       lGroups.add( getGroup(lResults.next()) );
                      
                       }
                       catch (Throwable e)
                       {
                       throw new RuntimeException(e);
                       }
                       finally
                       {
                       try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                       }
                      
                       return lGroups;
                       }
                      
                       public List<Group> findGroupsByUserAndGroupType(String iUserId, String iGroupType) {
                       return findGroupsByUser(iUserId);
                       }
                      
                       public User findUserById(String iUserId) {
                      
                       InitialDirContext lContext = null;
                       UserImpl lUser = null;
                      
                       try
                       {
                       lContext = getLDAPContext();
                      
                       NamingEnumeration<SearchResult> lResults = lContext.search(
                       getProps().getProperty("userBase"),
                       getProps().getProperty("findUserByIdSearch"),
                       new Object[]{ iUserId },
                       lSearchControls );
                      
                       if ( lResults.hasMore() )
                       lUser = getUser(lResults.next());
                       }
                       catch (Throwable e)
                       {
                       throw new RuntimeException(e);
                       }
                       finally
                       {
                       try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                       }
                      
                       return lUser;
                       }
                      
                       public List<User> findUsers() {
                      
                       List<User> lUsers = new ArrayList<User>();
                       InitialDirContext lContext = null;
                      
                       try
                       {
                       lContext = getLDAPContext();
                      
                       NamingEnumeration<SearchResult> lResults = lContext.search(
                       getProps().getProperty("userBase"),
                       getProps().getProperty("findUsersSearch"),
                       lSearchControls );
                      
                       while ( lResults.hasMore() )
                       lUsers.add( getUser(lResults.next()) );
                       }
                       catch (Throwable e)
                       {
                       throw new RuntimeException(e);
                       }
                       finally
                       {
                       try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                       }
                      
                       return lUsers;
                       }
                      
                       public List<User> findUsersById(String... iUserIds) {
                      
                       List<User> lUsers = new ArrayList<User>(iUserIds.length);
                      
                       try
                       {
                       for (String lUserId : iUserIds) {
                       lUsers.add( findUserById(lUserId) );
                       }
                       }
                       finally
                       {
                      
                       }
                      
                       return lUsers;
                       }
                      
                       public List<User> findUsersByGroup(String iGroup) {
                      
                       InitialDirContext lContext = null;
                       List<User> lUsers = new ArrayList<User>();
                      
                       try
                       {
                       lContext = getLDAPContext();
                      
                       NamingEnumeration<SearchResult> lResults = lContext.search(
                       getProps().getProperty("roleBase"),
                       getProps().getProperty("findUsersByGroupSearch"),
                       new Object[]{ iGroup },
                       lSearchControls );
                      
                       while ( lResults.hasMore() )
                       lUsers.add( getUser(lResults.next()) );
                       }
                       catch (Throwable e)
                       {
                       throw new RuntimeException(e);
                       }
                       finally
                       {
                       try { if (lContext != null ) lContext.close(); } catch (NamingException e) { }
                       }
                      
                       return lUsers;
                       }
                      
                       private UserImpl getUser(SearchResult iResult) throws NamingException, IOException {
                      
                       final String iUserId = getAttributeValue(iResult, getProps().getProperty("userIdAttr"));
                       final String lEmail = getAttributeValue(iResult, getProps().getProperty("userEmailAttr"));
                       final String lFirstname = getAttributeValue(iResult, getProps().getProperty("userFirstNameAttr"));
                       final String lLastname = getAttributeValue(iResult, getProps().getProperty("userLastNameAttr"));
                      
                       final UserImpl lUser = new UserImpl(iUserId, lFirstname, lLastname);
                       lUser.setBusinessEmail(lEmail);
                      
                       return lUser;
                       }
                      
                       private List<User> getUsers(SearchResult iResult) throws NamingException, IOException {
                       NamingEnumeration<?> lAllAttrValues = null;
                      
                       final List<User> lUsers = new ArrayList<User>();
                       final Attribute lAttr = iResult.getAttributes().get(getProps().getProperty("memberOfAttr"));
                      
                       if ( lAttr != null )
                       lAllAttrValues = lAttr.getAll();
                      
                       while ( lAllAttrValues.hasMore() )
                       {
                       String lUserDN = (String) lAllAttrValues.next();
                       lUsers.add( findUserById(getExtractedIdFromDN(lUserDN)) );
                       }
                       return lUsers;
                       }
                      
                       private GroupImpl getGroup(SearchResult iResult) throws NamingException, IOException {
                      
                       final String iGroupId = getAttributeValue(iResult, getProps().getProperty("groupIdAttr"));
                       final GroupImpl lGroup = new GroupImpl(iGroupId);
                      
                       return lGroup;
                       }
                      
                       private String getExtractedIdFromDN(String iGroupDN) {
                       StringTokenizer lTok = new StringTokenizer(iGroupDN, ",");
                      
                       String lGroupCN = lTok.nextToken();
                      
                       return lGroupCN.substring(3);
                       }
                      
                       private String getAttributeValue(SearchResult iResult, String iAttributeName) throws NamingException {
                       NamingEnumeration<?> lAllAttrValues = null;
                       Attribute lAttr = iResult.getAttributes().get(iAttributeName);
                      
                       if ( lAttr != null )
                       lAllAttrValues = lAttr.getAll();
                      
                       if ( lAllAttrValues != null && lAllAttrValues.hasMore() )
                       return (String) lAllAttrValues.next();
                       else
                       return null;
                       }
                      
                       private InitialDirContext getLDAPContext() throws NamingException, IOException {
                       InitialDirContext lLdapCtx = null;
                      
                       // Set up LDAP configuration settings
                       Hashtable<String, String> lContextValues = new Hashtable<String, String>();
                      
                       lContextValues.put("java.naming.ldap.version", getProps().getProperty("ldapVersion"));
                       lContextValues.put( Context.INITIAL_CONTEXT_FACTORY, getProps().getProperty("initialContextFactory"));
                       lContextValues.put( Context.SECURITY_AUTHENTICATION, getProps().getProperty("authentication"));
                       lContextValues.put( Context.REFERRAL, getProps().getProperty("referral"));
                       lContextValues.put( Context.PROVIDER_URL, getProps().getProperty("connectionURL"));
                       lContextValues.put( Context.SECURITY_PRINCIPAL, getProps().getProperty("connectionUsername"));
                       lContextValues.put( Context.SECURITY_CREDENTIALS, getProps().getProperty("connectionPassword"));
                      
                       // Make LDAP connection
                       lLdapCtx = new InitialDirContext(lContextValues);
                      
                       return lLdapCtx;
                       }
                      
                       private static Properties getProps() throws IOException
                       {
                       if ( props == null )
                       {
                       props = new Properties();
                       props.load( ClassLoader.getSystemClassLoader().getResourceAsStream("ldap.properties") );
                       }
                      
                       return props;
                       }
                      
                       /* The following methods won't be implemented */
                       public String createGroup(String arg0, String arg1, String arg2) {
                       throw new UnsupportedOperationException();
                       }
                      
                       public void createMembership(String arg0, String arg1, String arg2) {
                       throw new UnsupportedOperationException();
                       }
                      
                       public String createUser(String arg0, String arg1, String arg2, String arg3) {
                       throw new UnsupportedOperationException();
                       }
                      
                       public void deleteGroup(String arg0) {
                       throw new UnsupportedOperationException();
                       }
                      
                       public void deleteMembership(String arg0, String arg1, String arg2) {
                       throw new UnsupportedOperationException();
                       }
                      
                       public void deleteUser(String arg0) {
                       throw new UnsupportedOperationException();
                       }
                      }
                      


                      ldap.properties

                      initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
                      connectionURL=ldap://server
                      authentication=simple
                      connectionUsername=Username
                      connectionPassword=Password
                      timeout=3000
                      referral=follow
                      ldapVersion=3
                      
                      userIdAttr=uid
                      userEmailAttr=mail
                      userFirstNameAttr=givenname
                      userLastNameAttr=sn
                      userDNAttr=cn
                      memberOfAttr=member
                      groupIdAttr=cn
                      
                      # Lotus Domino
                      userBase="ou=BBBXXX_PL,o=BBBXXX"
                      roleBase=
                      
                      findGroupByIdSearch=(&(cn={0})(objectclass=dominoGroup))
                      findGroupIdsByUserSearch=
                      findGroupsByUserSearch=(&(member=cn={0},ou=BBBXXX_PL,o=BBBXXX)(objectclass=dominoGroup))
                      findUserByIdSearch=(&(cn={0})(objectclass=dominoPerson))
                      findUsersSearch=(&(objectclass=dominoPerson))
                      findUsersByGroupSearch=(&(cn={0})(objectclass=dominoGroup))
                      
                      # Active Directory
                      #userBase="cn=users,dc=int,dc=bbbxxx,dc=pl"
                      #roleBase="cn=users,dc=int,dc=bbbxxx,dc=pl"
                      
                      #findGroupByIdSearch=(&(cn={0})(objectclass=group))
                      #findGroupIdsByUserSearch=
                      #findGroupsByUserSearch=(&(member=cn={0},CN=Users,DC=int,DC=bbbxxx,DC=pl)(objectclass=group))
                      #findUserByIdSearch=(&(|(cn={0})(samAccountName={0}))(objectclass=user))
                      #findUsersSearch=(&(objectclass=user))
                      #findUsersByGroupSearch=(&(cn={0})(objectclass=group))
                      
                      [list=][list=]