Administer > Manage instances > WCS instance > Configure directory services (LDAP) with WebSphere Commerce


LDAP customization points

There are customization points available when integrating with LDAP to handle extra synchronization logic.

A new task command called com.ibm.commerce.member.syncbeans.commands.LDAPIntegrationCmd contains methods that can be overridden. Since LDAP integration requires a site-wide implementation, only one implementation of this command can be registered, using store 0. The methods are called at varying points in the LDAP integration scenarios:


Support for different organizational hierarchies in LDAP and WebSphere Commerce database

IBM recommends that the organization structure and distinguished names on the LDAP server match what is in WebSphere Commerce database. If the organization hierarchies match, but the distinguished names of Root Organization and Default Organization in LDAP are different than the default values in WebSphere Commerce, then the Integration Wizard can handle renaming the DN values in WebSphere Commerce during the initial setup of WebSphere Commerce with LDAP. If, however, the organization hierarchies are different, for example, the LDAP server has a relatively flat structure while WebSphere Commerce database has a more complex structure, the recommended approach is still to make the LDAP structure the same as the WebSphere Commerce organizational structure. However, if this is not possible, override the default implementation of the following methods of the LDAPIntegrationCmd task command to handle the mapping between the LDAP DNs and the WebSphere Commerce database DNs:

public String getLDAPDN(String astrCommerceDN) throws ECException;
 

public String getCommerceDN(String astrLDAPDN, DataObject adoMember) throws ECException;
 

In the case that the mapping between organization DNs is one-to-many, for example, one organization in LDAP maps to multiple buyer organizations in WebSphere Commerce, these organizations must be manually preloaded into both systems, rather than relying on the OrganizationSyncBean to automatically create them.

In all cases, WebSphere Commerce requires the Root Organization (-2001) be the common ancestor of all other organizations, and the Default Organization (-2000) exist directly under the Root Organization.


Callout to do extra processing during Single sign on (SSO) and Logon

In LogonCmdImpl.java, when the authentication mode is set to LDAP, and the authentication is successful, the following method of LDAPIntegrationCmdImpl.java is called to allow further processing to be done:

public void postLogonProcessing(UserAccessBean aUserAccessBean) throws ECException;

UserSyncBean.findByMemberId(aUserAccessBean.getMemberId()) can be called to get the UserSyncBean. From UserSyncBean.getLDAPMember() returns a DataObject representing the object in LDAP, which can be used for any further processing.

After single sign on takes place, the following method is called to handle any additional processing:

public void postSingleSignOnProcessing(UserSyncBean aUserSyncBean) throws ECException;


Make use of member group information of users in LDAP

The following is a sample implementation that shows how the member group information of a user in LDAP can be used to assign roles to the user in WebSphere Commerce:

/**
 * This method is called after single sign-on has taken place.
 * It enables extra processing to take place. 
 *
 * Behavior: 
 * 
 *
 * Get the LDAP groups that the user belongs to from the UserSyncBean's LDAP data object.
 * 
 * If the user belongs to the "cn=csr,cn=groups,o=root organization" LDAP group, assign 
 * them the CSR role in Root Organization, if they don't have that role already.
 * 
 * If the user belongs to the "cn=gold customers,cn=groups,o=root organization" LDAP 
 * group, include them in the corresponding WC member group: "gold customers", if they 
 * don't already belong to it.
 * 
 * @param aUserSyncBean Contains information about the user that has authenticated. 
 * @throws ECException Thrown if an error occurs.
 */
public void postSingleSignOnProcessing(UserSyncBean aUserSyncBean) throws ECException{

  final String METHODNAME = "postSingleSignOnProcessing(UserSyncBean aUserSyncBean)";
 
  DataObject doLDAPMember = aUserSyncBean.getLDAPMember();
 
  if (doLDAPMember == null) {
    return;
   }

  //Get the groups that the user belongs to in LDAP
  List<DataObject>
 lstGroups = doLDAPMember.getList( SchemaConstants.DO_GROUPS);
   Iterator<DataObject>
 iterGroups = lstGroups.iterator();
 
  //Get the groups the user belongs to and then synch to WC DB's MBRROLE or MBRGRPMBR
  while (iterGroups.hasNext()) {
    DataObject doGroup = iterGroups.next();
     DataObject doID = doGroup.getDataObject(SchemaConstants.DO_IDENTIFIER);
     String strGroupName = doID.getString(SchemaConstants.PROP_UNIQUE_NAME);
 
    try{
      if ("cn=csr,cn=groups,o=root organization".equals(strGroupName)) {
        //Assign the user the CSR role in the Root Organization
        try {
          MemberRoleCache.findByMemberIdRoleIdOrgEntityId(
              Long.valueOf(aUserSyncBean.getMemberId()), 
              CSR_ROLE,               ROOT_ORG);
         } catch (FinderException e) {
          // Role assignment does not exist, so create it
          new MemberRoleAccessBean(
              Long.valueOf(aUserSyncBean.getMemberId()), 
              CSR_ROLE,               ROOT_ORG);
         } 
      } else if (GOLD_CUST_LDAP_GROUP.equals(strGroupName)) {

        MemberGroupAccessBean abMbrGrp = null;
         try {
          abMbrGrp = MemberGroupCache.findByOwnerName(
              ROOT_ORG, 
              GOLD_CUST_WC_GROUP);
         } catch (FinderException e) {
          ECTrace.trace(ECTraceIdentifiers.COMPONENT_USER, CLASSNAME, METHODNAME, "Member group does not exist: " + GOLD_CUST_LDAP_GROUP);
 
          continue;
 // skip to next iteration in the loop
        }


        //Assign the user to this member group in Commerce if it doesn't already exist
        try {
          MemberGroupMemberCache.findByPrimaryKey(
              abMbrGrp.getMbrGrpId(), 
              aUserSyncBean.getMemberId());
         } catch (FinderException e) {
          //Since the user doesn't belong to member group, add it now
          new MemberGroupMemberAccessBean(
              abMbrGrp.getMbrGrpIdInEJBType(), 
              Long.valueOf(aUserSyncBean.getMemberId()));
         }

      }
    } catch (NamingException e) {
      throw new ECSystemException(
          ECMessage._ERR_NAMING_EXCEPTION, 
          CLASSNAME, 
          METHODNAME, 
          ECMessageHelper.generateMsgParms(e), 
          e);
     } catch (RemoteException e) {
      throw new ECSystemException(
          ECMessage._ERR_REMOTE_EXCEPTION, 
          CLASSNAME, 
          METHODNAME, 
          ECMessageHelper.generateMsgParms(e), 
          e);
     } catch (CreateException e) {
      throw new ECSystemException(
          ECMessage._ERR_CREATE_EXCEPTION, 
          CLASSNAME, 
          METHODNAME, 
          ECMessageHelper.generateMsgParms(e), 
          e);
     } catch (FinderException e) {
      throw new ECSystemException(
          ECMessage._ERR_FINDER_EXCEPTION, 
          CLASSNAME, 
          METHODNAME, 
          ECMessageHelper.generateMsgParms(e), 
          e);
     }
  }
} 


Callout to do extra processing in SyncBean

The following method can be overridden to do extra processing whenever LDAP is being updated using a sync bean:

public void LDAPIntegrationCmd.postUpdateToLDAP (UserSyncBean userSyncBean) throws ECException;

The following method can be overridden to do extra processing whenever the WebSphere Commerce database is being updated by data from LDAP:

public void LDAPIntegrationCmd.postRefreshFromLDAP (UserSyncBean userSyncBean) throws ECException;


Synchronize extra data

UserSyncBean and OrganizationSyncBean read and write data to the database as well as to LDAP. Each class reads and writes to a default set of WebSphere Commerce database tables. Each of these tables has a corresponding sync helper data object (DO) class that is used by the sync bean to read and write to the table:

UserSyncBean
DO class Database Table
UserDO USERS
UserRegistryDO USERREG
UserDemographicsDO USERDEMO
SelfAddressDO ADDRESS (SELF ADDRESS)
BusinessProfileDO BUSPROF
UserProfileDO USERPROF
MemberAttributesDO MBRATTRVAL

OrganizationSyncBean
DO Class Database Table
OrgEntityDO ORGENTITY
SelfAddressDO ADDRESS (SELF ADDRESS)
MemberAttributesDO MBRATTRVAL

The DO classes to include for each sync bean can be specified and changed from the default implementation. For example, the following is the default implementation of LDAPIntegrationCmd.getUserDOs():

public Vector getUserDOs() {
        
        Vector vUserDOs = new Vector(7);
         
        vUserDOs.add(new UserDO());
         vUserDOs.add(new UserRegistryDO());
         vUserDOs.add(new UserDemographicsDO());
         vUserDOs.add(new SelfAddressDO());
         vUserDOs.add(new BusinessProfileDO());
         vUserDOs.add(new UserProfileDO());
         vUserDOs.add(new MemberAttributesDO());
         
        return vUserDOs;
     }

The task command can be extended, and more DO classes can be added to synchronize with new custom user tables.

The following is the default implementation of LDAPIntegrationCmd.getOrganizationDOs():

public Vector getOrganizationDOs() {
        
        Vector vUserDOs = new Vector(3);
         
        vUserDOs.add(new OrgEntityDO());
         vUserDOs.add(new SelfAddressDO());
         vUserDOs.add(new MemberAttributesDO());
         
        return vUserDOs;
     }

Similar to the preceding example, the task command can be extended, and more DO classes can be added to synchronize with new custom organization tables.


Previous topic: Test the LDAP configuration


+

Search Tips   |   Advanced Search