2007/07/03
3 Jul, 2007

Configuring the User Management Service - An SOA Component

  • Dimuthu Leelarathne
  • Architect - WSO2

user managerThe User Manager service is designed to be a component in an SOA application. It can be used in an SOA application to provide user management functions. It is designed to be deployed in the Axis2 engine as a SOAP service. The user manager service can be configured to perform different functions by adding parameters to axis2.xml of the Axis2 server. For example, it can be configured to talk to an RDBMS or a JNDI user store by adding parameters to the axis2.xml.

There are many advantages of using the User Manager in an SOA application.

The user manager service can be configured to,

  • Add, read, edit, delete, and authenticate users in a JDBC user store through a JDBC driver
  • Read, edit, delete, and authenticate users in an LDAP directory. (Add is not supported.)
  • Add, read, edit, delete and authenticate users through hibernate technology.
  • Read and write into the existing user store, e.g., the company LDAP directory or an existing JDBC database.
  • Work with custom "user" objects, i.e., it can manage any class implementing the following interface.

      org.wso2.commons.usermanager.elements.User.java

  • Work with custom realms, because the user manager service has a plug-in architecture.

UserManager

 

Figure1: The user manager service as an SOA component in an application.

 

The source code of the User Manager Service is available at

https://wso2.com/repos/wso2/trunk/commons/usermanager/

 

First this tutorial describes the basic usage, i.e., how to add, edit, delete, and authenticate users in the built-in database of the User Manager. The default built-in database will store only the username and password of the user.

Then the tutorial gives a pointer to the client API.

The next section of the tutorial focuses on how to configure the user manager. The user manager's power is in its configurations. It can be configured to read and write into any new or existing LDAP or RDBMS user store. Configuration is done by adding parameters/values into axis2.xml. The tutorial describes how to configure the three built-in realms. These descriptions are followed by the most powerful option of all, which is coding your own custom realm.

 

Using the User Manager with a Built-in User and Database

The user manager is shipped with the capabilities to manage a simple user, which stores only the username and password. It is configured to use a Derby database named “UserDatabase”, which has a single table with the columns User name and Password.

  1. Download and build the User Manager.

    1. Install Maven2.
    2. Download the source from :

      WSO2 repository

    3. Build UserMan by typing mvn clean install.

      This will create a UserMan.aar in the modules/userman-service/target directory.

  2. Create the default database by running the scripts. Change the directory to "modules/userman-core/resources".
    • Windows users please execute the create_default_db.bat command in the command prompt.

    • Unix users please execute create_default_db.sh
    • These scripts will create a directory named "UserDatabase" in the current directory. This is the database.

  3. Find the axis2.xml file of your Aixs2 server. If you are running the Axis2 standalone server, then the axis2.xml is available inside Axis2_HOME/repository/conf. If you are using Tomcat, it is inside the “conf” directory.

  4. Add the following parameter, where “dbpath” is the complete path to your database.

    <parameter name="userman.connection.url">jdbc:derby:/dbpath/UserDatabase</parameter>

    If this parameter is not present, then a “NullPointer Exception” will be thrown from the server.

  5. Drop the UserMan.aar to your Axis2 service repo.

    Congratulations!! Now the User Management service is working.

  6. You can use the client to invoke the methods in the User Manager -which is explained in the following section.

Client API : Talking to the User Manager Service

Methods in the Axis service can be invoked by using the User Manager client API. Therefore, the application only sees a simple set of methods, and the complexity is handled by the user manger client. Developers must provide the end point address and the invocation parameters. Please refer to the API: org.wso2.commons.usermanager.client.UserManagerClient

Understanding Configuration Parameters

Basic authentication can be carried out using the default scenario, but the User Manager is built to be configured to handle much more. Let's understand the parameters that we use to configure the user store. The rule of the User Manager service is as follows:

When reading parameters, the first priority is given to the axis2.xml, i.e., if the parameters are not present in the axis2.xml then the default parameters are loaded or else a UserManager exception will be thrown.

 

Available parameters and their description. The next section describes how to use the parameters in detail.


Parameter Name

Usage

Description

userman.userbase.driver_type

Type of connection to the Userstore

 

Indicates the type of connectivity to the user store.

When using JDBC ( default), org.wso2.commons.usermanager.realm.
generic.GenericJDBCRealm

When using JNDI, org.wso2.commons.usermanager.realm.
generic.GenericJNDIRealm

For hibernate, org.wso2.commons.usermanager.realm.
generic
.HibernateRealm

userman.connection.url JDBC/JNDI Connection URL

For JNDI ldap: //host-ip:port Normally port is 389.

For JDBC MySQL jdbc:mysql://localhost/ database_name

For JDBC Embedded derby jdbc:derby:path/database_name

userman.connection.name JDBC/JNDI The username used when UserManager creates the connection to the JNDI or JDBC
userman.connection.pass JDBC/JNDI Password of the connection

userman.jdbc.driver

Mandatory for JDBC

Indicates the JDBC driver class.

When using MySQL, com.mysql.jdbc.Driver

userman.jdbc.user_table

Mandatory for JDBC

Name of the user table

userman.jdbc.username_col

Mandatory for JDBC

Name of the username column in the user table

userman.userclass

Indicates the user class.

JDBC/JNDI/Hibernate

The default value is, org.wso2.commons.usermanager.elements.
impl.UserBase

userman.user.fields

 

 

JDBC/JNDI

Comma separated list of attributes of the user object. Used with the parameter “userman.user.binding” to show the mapping. Please refer to step2 in Configuring the User Manager

userman.user.binding

JDBC/JNDI

Shows the mapping between object attributes and user store attributes. Used with “userman.user.fields” to show the mapping. Please refer to step2 in Configuring the User Manager

userman.jndi.digest_algo

Mandatory when using JNDI

Digest algorithm of the password attribute in the LDAP directory.

userman.jndi.password_attrId

Mandatory when using JNDI

Attribute ID of the password.

userman.jndi.user_pattern

Mandatory when using JNDI

User pattern to be used when searching for users.

 


Configuring the User Manager

The user manager is configured using two main steps. They are:

Step 1 : Picking a user implementation. This step must be carried out by the application developer, because he is the one who knows what information of the user is needed.

Step 2: Configuring the user store. You can connect to a user store using one of the following three approaches.

  • Configure the user manager to work with a new or existing relational database from any vendor using the JDBC driver.
  • Configure the user manager to work with a JNDI directory.
  • Configure the user manager using hibernate technology.
  • Coding a custom realm.

This step is carried out by the system administrators at the user end. If this step is carried out by the application developer, it will limit the flexibility.

Now let's look us these two steps in detail.

Step 1: Picking a User Object

  1. First we need a class to store the user information. Write a class implementing the interface. org.wso2.commons.usermanager.elements.User.java
  2. The following is an example. This is the default implementation packaged in the user manager. It is a very basic user class which stores the username and password.

    org.wso2.commons.usermanager.elements.impl.UserBase

    If you need to read or write more information from the user store, include more attributes in the class.

  3. The user class must use standard JavaBean naming conventions for property getter and setter methods.
  4. If you are using a custom user class, compile it and add it to the classpath.
  5. Then indicate the user class in the axis2.xml file. If you have decided to use the build-in user object there is no need to indicate it in the axis2.xml file. It is loaded automatically.
  6. This is how you indicate a custom user in axis2.xml

    <parameter name="userman.userclass">org.wso2.some.service.MyUser</parameter>

 

Step 2: Configuring the User Store

  • Configuring the user manager to connect to a database through a JDBC driver

The user manager can be configured to use existing or new databases from different vendors. This is handled by the JDBC realm of the user management service, which is the default method. A JDBC realm can add, edit, and delete users and it can also execute SQL statements on a set of users and return an array of users.

The user manager must know how to load and store user objects in the correct database. You have to indicate this data in the axis2.xml file.

 

  1. MySQL and Derby databases are included in the usermanager.aar archive. If you are using some other driver, it must be added to the classpath. Add the “"userman.jdbc.driver"” parameter to the axis2.xml file indicating the driver class to the UserManager.
  2. The URL of the database must be given in the axis2.xml. If “dbpath” is the path to the database, then the connection URL would be,

    <parameter name="userman.connection.url">jdbc:derby:dbpath/UserDatabase </parameter>

  3. Specify the username and password for the database connection by adding "userman.connection.name" and "userman.connection.pass" parameters in axis2.xml
  4. User objects must map to a table in the SQL database. In this table, each row will carry data of a single user. The username must map into a column in the User table. You have to indicate the mapping in the axis2.xml as follows. The mapping for the built-in user and the database is given below.
  5. <parameter name="userman.jdbc.username_col">username</parameter>

    <parameter name="userman.jdbc.user_table">users</parameter>

  6. Attributes in the User object must map into the columns in the mentioned database. The attributes that do not map into the columns will not be persistent in the database. The mapping is indicated by a couple of parameters in the axis2.xml file. The parameter "userman.user.fields" has a list of attributes in the object, and "userman.user.binding" has the mapping list of the order of the columns. Data types of the correlating fields and columns must match.

    <parameter name="userman.user.fields">status, name, password</parameter>

    <parameter name="userman.user.binding">status, username, pass</parameter>

  7. Build UserManager and drop it into the repository of the axis server.

    Now the User Manager Service is up and running with a custom user and its mapping database.

  • Configuring the user manager to work with an LDAP directory

The user manager can be configured to use the company's existing LDAP directory or a new LDAP directory. This is handled by the JNDI realm of the user manager. It cannot add users in the LDAP directory, but it can read, delete users, and also modify their attributes. LDAP directories have a standard set of digest algorithms. Currently, the user manager assumes that all passwords are digested using a single algorithm.

  1. Add the following parameter to axis2.xml. This will tell the UserManager to use the JNDI realm.
  2. <parameter name="userman.userbase.driver_type">org.wso2.commons.usermanager
    .realm.generic.GenericJNDI</parameter>

  3. Specify the connection details to the JNDI directory

    userman.connection.name - ldap://host-ip:port port is normally 389

    userman.connection.pass - username to make the connection to the database

    userman.connection.url- password of the connection

  4. Attributes of the User object have to map to attributes in the LDAP directory user. The mapping is indicated by a couple of parameters in the axis2.xml file, just as in the JDBC realm. The parameter "userman.user.fields" has a list of attributes in the object, and "userman.user.binding" has the mapping list of the attribute IDs of the LDAP directory in the mapping order.
  5. <parameter name="userman.user.fields">status, name, password</parameter>

    <parameter name="userman.user.binding">status, username, pass</parameter>

  6. Passwords of users are digested and then stored in the LDAP directory as an attribute of the user. Specify the attribute ID of the password in axis2.xml, by using the parameter " userman.jndi.password_attrId"
  7. Specify the digesting algorithm of the password in axis2.xml, by using the parameter " userman.jndi.digest_algo". The supporting algorithms are MD5, pSHA1.
  8. Specify the search pattern for the user in axis2.xml as follows. The '0' (zero) will be replaced by the name when searching for users.

    <parameter name="userman.jndi.user_pattern">uid={0},ou=People,dc=wso2,dc=or</parameter>

  9. Build the User Manager and drop it into the repository of the axis server.
  • Configuring the user manager to use hibernate technology

The user manager can be configured to use hibernate for object relational mapping. Hibernate is a mature ORM technology, but the user manager provides a very basic implementation. You can always write your own custom hibernate realm using a preferred session/transaction management architecture.

Please refer to Coding a Custom Realm on how to code your own realms. This implementation creates a hibernate session per Web service call.

  1. Add the following to axis2.xml. This will tell the user manager to use the hibernate realm.
  2. <parameter name="userman.userbase.driver_type">org.wso2.commons.usermanager.realm.generic.
    HibernateRealm</parameter>

  3. If you are using a custom user class, then write the hibernate mapping file and place it next to the custom user Java class.

    Name the file with the suffix hbm.xml and specify it in axis2.xml using the parameter "userman.hibernate.cfg_file". Refer to https://www.hibernate.org for how to write a hibernate config file.

  4. Then write the “hibernate.cfg.xml” to configure the hibernate realm and place it in the classpath. Refer https://www.hibernate.org for more information.

    If you are using a JDBC driver other than MySQL and Derby, you have to add it to the classpath.

  5. Build User Manager and drop the .aar it into the repository of the axis server.
  • Coding a Custom Realm

The user manager has a plug-in architecture, which enables you to write your own realm. If you are not satisfied with the three built-in realms, you can code your own realm by following these steps.

  1. Carry out the first step, i.e., defining a user.
  2. Write your custom realm by implementing the interface org.wso2.commons.usermanager.realm.generic.UserBaseDriver The three built-in realms in the user manager also implement this interface.
  3. Compile and add the custom realm to the classpath.
  4. In axis2.xml specify the class by giving the parameter userman.userbase.driver_type.

    Let your class be “my.CustomRealm”. Then in axis2.xml, specify the following:

    <parameter name="userman.userbase.driver_type">my.CustomRealm</parameter>


Conclusion and Future Development

The key feature of the user manager is that it can be configured to talk to existing user stores and all the finer details will be transparent to your application. When requirements arise, new realms will be added to the user manager other than to the starting built-in realms. In the future, the User Manager will support user roles as well.

 

Author

Dimuthu Leelarathne, Senior Software Engineer - WSO2 Inc. dimuthul at wso2 dot com

 

 

About Author

  • Dimuthu Leelarathne
  • Architect
  • WSO2