Introduced in Feature Pack 3

Extending the generic table loader to encrypt user passwords

Introduced in Feature Pack 3 In this lesson, you create a new Java class to implement the com.ibm.commerce.foundation.dataload.config.ColumnHandler interface to encrypt user password data.

About this task

Create a custom column handler to resolve data from database columns that are based on input values that cannot be mapped to the column value through the configuration. For example, if your input to populate the password column in the database is a clear text password, but the column in the database table expects an encrypted value, create a custom column handler to encrypt the clear text password and return an encrypted password from the resolveColumnValue() method.

Procedure

  1. Open WebSphere Commerce Developer.
  2. Switch to the Java EE perspective.
  3. In the Enterprise Explorer view, navigate to WebSphereCommerceServerExtensionsLogic > src.
  4. Right-click src; then click New > Package.
  5. In the Name field, type com.mycompany.commerce.dataload.password. Click Finish to create a new package.
  6. Right-click com.mycompany.commerce.dataload.password; then click New > Class.
  7. In the Name field, type PasswordEncryptionHandler.
  8. From the Superclass field, click Browse to browse for the com.ibm.commerce.foundation.dataload.config.AbstractColumnHandler abstract class; then click OK.
  9. Click Finish to create the class.
    A new file opens for editing.
  10. Paste the following code snippet into the new file:
    package com.mycompany.commerce.dataload.password;
    
    import java.util.Map;
    
    import com.ibm.commerce.foundation.common.util.logging.LoggingHelper;
    import com.ibm.commerce.foundation.dataload.config.AbstractColumnHandler;
    import com.ibm.commerce.foundation.dataload.exception.DataLoadException;
    import com.ibm.commerce.foundation.dataload.object.ExtendedTableDataObject;
    import com.ibm.commerce.member.dataload.helper.MemberDataLoadHelper;
    import com.ibm.commerce.util.WCPasswordEncrypter;
    
    /**
     *The main purpose of the PasswordEncryptionHandler is to resolve the column value based
     * on the input values which cannot be simply mapped to the column value 
     * through the configuration. For example, to populate the password column in the
     * database, your input is a clear text password, but the column in the database expects
     * an encrypted value, you need to write a custom handler to encrypt the clear
     * password and return an encrypted password from the method resolveColumnValue().
     */
    public class PasswordEncryptionHandler extends AbstractColumnHandler {
    
    	
    	private final static String CLASSNAME = PasswordEncryptionHandler.class.getName();
    	private static final java.util.logging.Logger LOGGER = LoggingHelper.getLogger(PasswordEncryptionHandler.class);
    	private static final String CUSTOM_KEY_CONFIG_LOCATION = "customKeyConfigLocation";
    	private static final String INSTANCE_CONFIG_LOCATION = "instanceConfigLocation";
    	
    	/**
    	 * Resolve the column value based on the input parameters passed in.
    	 * The parameter map will contain the map from LOGONID to the value of logonId.
    	 * The extenededTableDataObject represents the row of the table.
    	 * @param parameterMap a parameter map which are name-value pairs 
    	 * defined in the configuration.
    	 * @param extenededTableDataObject the current table data object which contains
    	 * the table configuration and some column values which have been
    	 * resolved so far. 
    	 * @return resolved new column value for the encrypted password
    	 * @throws DataLoadException if there are some errors to resolve the value.
    	 */
    	public String resolveColumnValue(Map<String, String> parameterMap,
    			ExtendedTableDataObject extendedTableDataObject) throws DataLoadException {
    		// TODO Auto-generated method stub
    		final String METHODNAME = "resolveColumnValue";
    		/* Enable the log trace for the method */
    		if (LoggingHelper.isEntryExitTraceEnabled(LOGGER)){
    			LOGGER.entering(CLASSNAME, METHODNAME);
    		}
    		/* Call API to get the salt value */
    		String salt = MemberDataLoadHelper.generateSalt(); 1
    		/* Store the salt value back into the USREEG table */
    		extendedTableDataObject.addColumnData 2 ("SALT", salt);
    		
    		String password = parameterMap.get("logonPassword");
    		String InstanceconfigLocation = parameterMap.get(INSTANCE_CONFIG_LOCATION);
    		String customKeyConfigLocation = parameterMap.get(CUSTOM_KEY_CONFIG_LOCATION);
    		
    		String encryptedPWD = null;
    		
    		
    		try {
    			WCPasswordEncrypter encrypter = new WCPasswordEncrypter();
    			/* Provide the file location which the merchant key is stored in so that to initialize  the Merchant key registration */
    			encrypter.initializeKeyRegistry 3 (customKeyConfigLocation, InstanceconfigLocation);
    			
    		/*Encrypt the plain text password */
    		encryptedPWD = encrypter.encryptPassword 4 (password, salt);
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		if (LoggingHelper.isEntryExitTraceEnabled(LOGGER)) {
    			LOGGER.exiting(CLASSNAME, METHODNAME);
    		}
    		/* return the encrypted password */
    		return encryptedPWD ;
    	}
    
    
    	}
    1 generateSalt()
    Generates a random salt string with a length of 12 characters.
    2 extendedTableDataObject.addColumnData
    Extends com.ibm.commerce.foundation.dataload.object.TableDataObject to include more ID resolver information for certain database table columns. This class represents a row in a physical database table such as USERREG. addColumnData takes the column name and value as input for Salt and adds the value back to the SALT column in the USERREG database table.
    3 initializeKeyRegistry
    Initializes the key registry by providing one of the following parameters:
    customKeyConfigFilename
    Specifies the full path to the custom key configuration file when the merchant key is stored in an external medium.
    instanceXMLFilename
    Specifies the full path to the instance configuration XML file when the merchant key is stored within the instance configuration file.
    If both parameters are specified, an initial attempt is made to initialize the key registry with the custom key configuration file. If that fails, an attempt is made to initialize the key registry with the instance configuration file.
    4 encryptPassword
    Returns the WebSphere Commerce encrypted password with the given clear text password and salt. The caller of this method must first initialize the key registry by calling the initializeKeyRegistry(String instanceXMLFilename, String customKeyConfigFilename) method.