Points de personnalisation LDAP

Des points de personnalisation sont disponibles lorsque vous procédez à l'intégration à LDAP pour gérer la logique de synchronisation supplémentaire.

Une nouvelle instruction de tâche appelée com.ibm.commerce.member.syncbeans.commands.LDAPIntegrationCmd contient des méthodes qui peuvent être remplacées. Dans la mesure où l'intégration LDAP nécessite une implémentation côté site, une seule implémentation de cette commande peut être enregistrée à l'aide du magasin 0.

Les méthodes sont appelées à des points variables dans les scénarios d'intégration LDAP :

Prise en charge de différentes hiérarchies organisationnelles dans LDAP et la base de données HCL Commerce

Il est recommandé que la structure d'organisation et les noms distinctifs sur le serveur LDAP correspondent à ceux qui se trouvent dans la base de données HCL Commerce. Si les hiérarchies d'organisation concordent, mais que les noms distinctifs de l'organisation racine et de l'organisation par défaut dans LDAP sont différents des valeurs par défaut définies dans HCL Commerce, l'assistant d'intégration peut gérer les valeurs de nom distinctif restantes dans HCL Commerce lors del a configuration initiale de HCL Commerce avec LDAP. Si, toutefois, les hiérarchies organisationnelles sont différentes, par exemple, le serveur LDAP présente une structure relativement à plat alors que la base de données HCL Commerce possède une structure plus complexe, la méthode recommandée consiste néanmoins à faire de la structure LDAP la même que la structure organisationnelle HCL Commerce. Cependant, si cela ne s'avère pas possible, vous devez remplacer l'implémentation par défaut des méthodes suivantes de l'instruction de tâche LDAPIntegrationCmd, afin de traiter le mappage entre les noms distinctifs LDAP et les noms distinctifs de la base de données HCL Commerce :

public String getLDAPDN(String astrCommerceDN) throws ECException; 

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

Si le mappage entre des noms distinctifs d'organisation est de type un pour plusieurs, par exemple, une organisation dans LDAP est mise en correspondance avec plusieurs organisations d'acheteur dans HCL Commerce, ces organisations doivent être préchargées manuellement dans les deux systèmes ; elles ne sont pas créées automatiquement par OrganizationSyncBean.

Dans tous les cas, HCL Commerce nécessite que l'organisation racine (-2001) soit l'ancêtre commun de toutes les autres organisations et que l'organisation par défaut (-2000) existe directement sous l'organisation racine. HCL Commerce part du principe que l'organisation par défaut est l'organisation parente des clients grand public (B2C).

Exemple

/**
* Returns the LDAP DN that corresponds to a specified Commerce DN.
* By default, the following mapping is done: <ul>
* <li> "uid=xxx,o=buyer a organization,o=root organization" maps to "uid=xxx,o=internal,o=root organization"
*
* <li> "uid=yyy,o=buyer b organization,o=root organization" maps to "uid=yyy,o=internal,o=root organization"
*
* <li> DNs ending with "o=default organization,o=root organization" are changed to end with "o=testorg,o=root organization"
*
* <li> Otherwise, the input DN is returned.
* </ul>
*
* @param astrCommerceDN The Commerce DN.
* @return The LDAP DN.
* @exception ECException Thrown if an error occurs.
*/
public String getLDAPDN(String astrCommerceDN) throws ECException {

String strLDAPDN = astrCommerceDN;

if (astrCommerceDN.equals(BUYER_A_ORG_DN) ||
astrCommerceDN.equals(BUYER_B_ORG_DN) ) {

//Map "o=buyer x organization,o=root organization" to "o=internal,o=root organization"
strLDAPDN = INTERNAL_ORG_DN;
} else if ( astrCommerceDN.indexOf(BUYER_A_ORG_DN) > 0) {
int nIndex = astrCommerceDN.indexOf(BUYER_A_ORG_DN);
String strDNBeginning = astrCommerceDN.substring(0, nIndex);

//Map "uid=yyy,o=buyer a organization,o=root organization" to "uid=yyy,o=internal,o=root organization"

strLDAPDN = strDNBeginning + INTERNAL_ORG_DN;

} else if ( astrCommerceDN.indexOf(BUYER_B_ORG_DN) > 0) {
int nIndex = astrCommerceDN.indexOf(BUYER_B_ORG_DN);
String strDNBeginning = astrCommerceDN.substring(0, nIndex);

//Map "uid=yyy,o=buyer b organization,o=root organization" to "uid=yyy,o=internal,o=root organization"

strLDAPDN = strDNBeginning + INTERNAL_ORG_DN;

} else if ( astrCommerceDN.endsWith("o=default organization,o=root organization")) {
strLDAPDN = SyncBeanUtil.getRDN(astrCommerceDN)
+ ECMemberConstants.EC_LDAP_DN_SEPARATOR
+ "o=testorg,o=root organization";
}

return strLDAPDN;
}


/**
* Returns the Commerce DN that corresponds to a specified LDAP DN: <ul>
*
* <li> If the user belongs to the "buyer x organization" member
* group in LDAP, then the user belongs to "buyer x organization" in Commerce.
*
* <li> DNs ending with "o=default organization,o=root organization" are changed to end with "o=testorg,o=root organization"
*
* <li> Otherwise, the input DN is returned.
* </ul>
*
* @param astrLDAPDN The LDAP DN.
* @param adoMember The entity data object corresponding to the member.
* @return The Commerce DN.
* @exception ECException Thrown if an error occurs.
*/
public String getCommerceDN(String astrLDAPDN, DataObject adoMember)
throws ECException {

String strCommerceDN = astrLDAPDN;

if (astrLDAPDN.endsWith(INTERNAL_ORG_DN)) {

/**
* Get the group information for the user.
* If the user belongs to the "buyer x organization" member
* group in LDAP, then the user belongs to "buyer x
* organization" in Commerce, etc.
*/
List<DataObject> lstGroups = adoMember.getList( SchemaConstants.DO_GROUPS);
Iterator<DataObject> iterGroups = lstGroups.iterator();
while (iterGroups.hasNext()) {
DataObject doGroup = iterGroups.next();
DataObject doID = doGroup.getDataObject(SchemaConstants.DO_IDENTIFIER);
String strGroupName = doID.getString(SchemaConstants.PROP_UNIQUE_NAME);

if ( BUYER_A_MBRGRP_DN.equals(strGroupName) ) {

strCommerceDN = SyncBeanUtil.getRDN(astrLDAPDN)
+ ECMemberConstants.EC_LDAP_DN_SEPARATOR
+ BUYER_A_ORG_DN;

break;
} else if (BUYER_B_MBRGRP_DN.equals(strGroupName) ) {

strCommerceDN = SyncBeanUtil.getRDN(astrLDAPDN)
+ ECMemberConstants.EC_LDAP_DN_SEPARATOR
+ BUYER_B_ORG_DN;

break;
}
}
} else if (astrLDAPDN.endsWith("o=testorg,o=root organization")) {
strCommerceDN = SyncBeanUtil.getRDN(astrLDAPDN)
+ ECMemberConstants.EC_LDAP_DN_SEPARATOR
+ "o=default organization,o=root organization";
}
return strCommerceDN;
} 

Appel permettant d'autres traitements pendant la connexion unique et l'ouverture de session

Dans LogonCmdImpl.java, lorsque le mode d'authentification est paramétré sur LDAP et que l'authentification aboutit, la méthode suivante de LDAPIntegrationCmdImpl.java est appelée pour permettre l'exécution d'autres traitements :

public void postLogonProcessing(UserAccessBean aUserAccessBean) throws ECException;
UserSyncBean.findByMemberId(aUserAccessBean.getMemberId()) peut être appelé pour obtenir le UserSyncBean. UserSyncBean.getLDAPMember() renvoie un DataObject représentant l'objet dans LDAP, qui peut être utilisé pour tout traitement supplémentaire.
Une fois que la connexion unique est établie, la méthode suivante est appelée pour gérer tout traitement supplémentaire :

public void postSingleSignOnProcessing(UserSyncBean aUserSyncBean) throws ECException;

Utilisation d'informations de groupe de membres des utilisateurs dans LDAP

Voici un exemple d'implémentation expliquant comment les informations de groupe de membres d'un utilisateur dans LDAP peuvent servir à attribuer des rôles à l'utilisateur dans HCL 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);
    }
  }
} 

Appel permettant d'autres traitements dans SyncBean

La méthode suivante peut être remplacée pour l'exécution d'autres traitements, chaque fois que LDAP est mis à jour à l'aide d'un bean sync :

public void LDAPIntegrationCmd.postUpdateToLDAP (UserSyncBean userSyncBean) throws ECException;
La méthode suivante peut être remplacée pour l'exécution d'autres traitements, chaque fois que la base de données HCL Commerce est mise à jour par des données de LDAP :

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

Synchronisation de données supplémentaires

UserSyncBean et OrganizationSyncBean lisent et écrivent des données dans la base de données, ainsi que dans LDAP. Chaque classe lit et écrit des données dans un ensemble par défaut de tables de base de données HCL Commerce. Chacune de ces tables possède une classe d'objet de données auxiliaires de synchronisation correspondante qui est utilisée par le bean sync pour lire et écrire des données dans la table :
UserSyncBean
Classe DO Table de base de données
UserDO USERS
UserRegistryDO USERREG
UserDemographicsDO USERDEMO
SelfAddressDO ADDRESS (SELF ADDRESS)
BusinessProfileDO BUSPROF
UserProfileDO USERPROF
MemberAttributesDO MBRATTRVAL
OrganizationSyncBean
Classe d'objet de données Table de base de données
OrgEntityDO ORGENTITY
SelfAddressDO ADDRESS (SELF ADDRESS)
MemberAttributesDO MBRATTRVAL
Les classes d'objet de données à inclure pour chaque bean sync peuvent être spécifiées et modifiées à partir de l'implémentation par défaut. Par exemple, voici l'implémentation par défaut de 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;
    }
L'instruction de tâche peut être étendue et d'autres classes d'objet de données peuvent être ajoutées si vous voulez synchroniser avec de nouvelles tables d'utilisateur personnalisées.
Voici l'implémentation par défaut de LDAPIntegrationCmd.getOrganizationDOs() :

public Vector getOrganizationDOs() {
        
        Vector vUserDOs = new Vector(3);
        
        vUserDOs.add(new OrgEntityDO());
        vUserDOs.add(new SelfAddressDO());
        vUserDOs.add(new MemberAttributesDO());
        
        return vUserDOs;
    }
A l'instar de l'exemple précédent, l'instruction de tâche peut être étendue et d'autres classes d'objet de données peuvent être ajoutées si vous voulez synchroniser avec de nouvelles tables d'organisation personnalisées.