WSO2 Identity Server

WSO2 Identity Server Create Custom User Store

There are four types of  User Store managers available for WSO2 Identity Server

  • Microsoft Active Directory based User Store Manager.
  • Readonly LDAP User Store Manager.
  • ReadWrite LDAP User Store Manager.
  • Carbon Remote User Store Manager.
  • JDBC User Store Manager for RDBMS.
But Sometimes depend on your requirement you need to customise those pre-built user stores to suit your requirement for this purpose you need to develop your own custom user store manager.
In this article, I will show you how to build your own custom user store manager for existing JDBC user store manager
(01) First, create a new maven project from NetBeans
1
(02) Once Project created go to pom.xml file and add following dependencies
2

(03)

After configuring pom.xml file now your set to implement you own user store in order to develop custom user store for RDBMS you have three options,
  • Create User Store by extending the available JDBCUserStoreManager and overriding it available methods
  • Create User Store by extending the available AbstractUserStoreManager and override it methods
  • Create User Store by implementing the UserStoreManager interface

Using Either option above you can create custom user store for this tutorial I will use the second approach which is extending the JDBCUserStoreManager.

(04)

Create a new class called CustomUserStoreManager which extends the JDBCUserStoreManager class.

import java.security.Timestamp;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasypt.util.password.StrongPasswordEncryptor;
import org.wso2.carbon.user.api.RealmConfiguration;
import org.wso2.carbon.user.core.UserRealm;
import org.wso2.carbon.user.core.UserStoreException;
import org.wso2.carbon.user.core.claim.ClaimManager;
import org.wso2.carbon.user.core.profile.ProfileConfigurationManager;
import org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager;

/**
 *
 * @author isurangaperera
 */
public class CustomUserStoreManager extends JDBCUserStoreManager {

    private static final Log log = (Log) LogFactory.getLog(CustomUserStoreManager.class);
    private static final StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();

    public CustomUserStoreManager(RealmConfiguration realmConfig, Map<String, Object> properties, ClaimManager
           claimManager, ProfileConfigurationManager profileManager, UserRealm realm, Integer tenantId)
           throws UserStoreException {
       super(realmConfig, properties, claimManager, profileManager, realm, tenantId);
       log.info("CustomUserStoreManager initialized...");
   }
    
    @Override
   public boolean doAuthenticate(String userName, Object credential) throws UserStoreException {
       boolean isAuthenticated = false;
       if (userName != null && credential != null) {
           try {
               String candidatePassword = (String) credential;
 
               Connection dbConnection = null;
               ResultSet rs = null;
               PreparedStatement prepStmt = null;
               String sql = null;
               dbConnection = this.getDBConnection();
               dbConnection.setAutoCommit(false);
               // get the SQL statement used to select user details
               sql = this.realmConfig.getUserStoreProperty("SelectUserSQL");
               if (log.isDebugEnabled()) {
                   log.debug(sql);
               }
 
               prepStmt = dbConnection.prepareStatement(sql);
               prepStmt.setString(1, userName);
               // check whether tenant id is used
               if (sql.contains("UM_TENANT_ID")) {
                   prepStmt.setInt(2, this.tenantId);
               }
 
               rs = prepStmt.executeQuery();
               if (rs.next()) {
                   String storedPassword = rs.getString(3);
 
                   // check whether password is expired or not
                   boolean requireChange = rs.getBoolean(5);
                   java.sql.Timestamp changedTime;
                   changedTime = rs.getTimestamp(6);
                   GregorianCalendar gc = new GregorianCalendar();
                   gc.add(GregorianCalendar.HOUR, -24);
                   Date date = gc.getTime();
                   if (!(requireChange && changedTime.before(date))) {
                       // compare the given password with stored password using jasypt
                       isAuthenticated = passwordEncryptor.checkPassword(candidatePassword, storedPassword);
                   }
               }
               log.info(userName + " is authenticated? " + isAuthenticated);
           } catch (SQLException exp) {
               log.error("Error occurred while retrieving user authentication info.", exp);
               throw new UserStoreException("Authentication Failure");
           }
       }
       return isAuthenticated;
   }
 
   @Override
   protected String preparePassword(String password, String saltValue) throws UserStoreException {
       if (password != null) {
           // ignore saltValue for the time being
           log.info("Generating hash value using jasypt");
           return passwordEncryptor.encryptPassword(password);
       } else {
           log.error("Password cannot be null");
           throw new UserStoreException("Authentication Failure");
       }
   }
}

Deploying and configuring the custom user store manager

Do the following to deploy and configure the custom user store manager in your WSO2 product.

(01) Copy the artifact of your project (custom-userstore.jar, in this case) to the /repository/components/dropins directory. Also copy all OSGI bundles to this location. If you have any dependency .jar files, copy them to the/repository/components/lib directory.

(02) Change the configuration of the WSO2 product to use our custom implementation for user store management. To do this, open the

/repository/conf/user-mgt.xml file and change the UserStoreManager class.

<UserStoreManager class="com.wso2.custom.usermgt.CustomUserStoreManager">
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s