JBoss.orgCommunity Documentation

Chapter 17. JBoss Portal Identity Management

17.1. Identity management API
17.1.1. How to obtain identity modules services ?
17.1.2. API changes since 2.4
17.2. Identity configuration
17.2.1. Main configuration file architecture (identity-config.xml)
17.3. User profile configuration
17.4. Identity modules implementations
17.4.1. Database modules
17.4.2. Delegating UserProfile module
17.4.3. Database UserProfile module implementation

This chapter addresses identity management in JBoss Portal 2.6

Since JBoss Portal 2.6 there are 4 identity services and 2 identity related interfaces. The goal of having such a fine grained API is to enable flexible implementations based on different identity storage like relational databases or LDAP servers. The Membership service takes care of managing the relationship between user objects and role objects. The User Profile service is responsible for managing the profile of a user, it has database and LDAP implementations as well as a mode that combines data from both.

The advocated way to get a reference to the identity modules is by using JNDI:

import org.jboss.portal.identity.UserModule;
import org.jboss.portal.identity.RoleModule;
import org.jboss.portal.identity.MembershipModule;
import org.jboss.portal.identity.UserProfileModule;

[...]

(UserModule)new InitialContext().lookup("java:portal/UserModule");
(RoleModule)new InitialContext().lookup("java:portal/RoleModule");
(MembershipModule)new InitialContext().lookup("java:portal/MembershipModule");
(UserProfileModule)new InitialContext().lookup("java:portal/UserProfileModule");

Another way to do this is, if you are fimiliar with JBoss Microkernel architecture is to get the IdentityServiceController mbean. You may want to inject it into your services like this:

<depends optional-attribute-name="IdentityServiceController" proxy-type="attribute">
   portal:service=Module,type=IdentityServiceController
</depends>

or simply obtain in your code by doing a lookup using the portal:service=Module,type=IdentityServiceController name. Please refer to the JBoss Application Server documentation if you want to learn more about service MBeans. Once you obtained the object you can use it:

(UserModule)identityServiceController.getIdentityContext()
            .getObject(IdentityContext.TYPE_USER_MODULE);

(RoleModule)identityServiceController.getIdentityContext()
            .getObject(IdentityContext.TYPE_ROLE_MODULE);

(MembershipModule)identityServiceController.getIdentityContext()
            .getObject(IdentityContext.TYPE_MEMBERSHIP_MODULE);

(UserProfileModule)identityServiceController.getIdentityContext()
            .getObject(IdentityContext.TYPE_USER_PROFILE_MODULE);
         

Because in JBoss Portal 2.4 there were only UserModule , RoleModule , User and Role interfaces some API usages changed. Here are the most important changes you will need to aply to your code while migrating your aplication to 2.6:

In order to understand identity configuration you need to understand its architecture. Different identity services like UserModule, RoleModule and etc are just plain Java classes that are instantiated and exposed by the portal. So an *example* of UserModule service could be a plain Java bean object that would be:

As you see from this point of view, configuration just specifies what Java class will be used and how it should be used by portal as a service.

In JBoss Portal we provide a very flexible configuration. It is very easy to rearrange and customize services, provide alternative implementations, extend the existing ones or provide a custom identity model.

To grasp the full picture of the configuration of identity services let's start from its root component. Whole configuration and setup of identity components is done by the IdentityServiceController service. It brings to life and registers all other services such as UserModule, RoleModule, MembershipModule and UserProfileModule. IdentityServiceController is defined in jboss-portal.sar/META-INF/jboss-service.xml

<mbean
   code="org.jboss.portal.identity.IdentityServiceControllerImpl"
   name="portal:service=Module,type=IdentityServiceController"
   xmbean-dd=""
   xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
   <xmbean/>
   <depends>portal:service=Hibernate</depends>
   <attribute name="JndiName">java:/portal/IdentityServiceController</attribute>
   <attribute name="RegisterMBeans">true</attribute>
   <attribute name="ConfigFile">conf/identity/identity-config.xml</attribute>
   <attribute name="DefaultConfigFile">conf/identity/standardidentity-config.xml</attribute>
</mbean>

We can specify a few options here:

The file describing portal identity services contains three sections:

<identity-configuration>
   <datasources>
      <!-- Datasources section -->
      <datasource> ... </datasource>
      <datasource> ... </datasource>
      ...
   </datasources>
   <modules>
      <!-- Modules section -->
      <module> ... </module>
      <module> ... </module>
      ...
   </modules>
   <options>
      <!-- Options section -->
      <option-group> ... </option-group>
      <option-group> ... </option-group>
      ...
   </options>
</identity-configuration>

By default you can find it in jboss-portal.sar/conf/identity/identity-config.xml

Modules are core service components like UserModule, RoleModule and etc.

<module>
   <!--type used to correctly map in IdentityContext registry-->
   <type>User</type>
   <implementation>DB</implementation>

   <!--name of service and class for creating mbean-->
   <service-name>portal:service=Module,type=User</service-name>
   <class>org.jboss.portal.identity.db.HibernateUserModuleImpl</class>

   <!--set of options that are in the instantiated object-->
   <config>
      <option>
         <name>sessionFactoryJNDIName</name>
         <value>java:/portal/IdentitySessionFactory</value>
      </option>
      <option>
         <name>jNDIName</name>
         <value>java:/portal/UserModule</value>
      </option>
   </config>
</module>

This section provides common options that are accessible by identity modules. We set options here that may need to be shared. They are grouped, and can have many values:

<options>
<!--Common options section-->
<option-group>
   <group-name>common</group-name>
   <option>
      <name>userCtxDN</name>
      <value>ou=People,dc=example,dc=com</value>
   </option>
   <option>
      <name>uidAttributeID</name>
      <value>uid</value>
   </option>
   <option>
      <name>passwordAttributeID</name>
      <value>userPassword</value>
   </option>
   <option>
      <name>roleCtxDN</name>
      <value>ou=Roles,dc=example,dc=com</value>
   </option>
   <option>
      <name>ridAttributeId</name>
      <value>cn</value>
   </option>
   <option>
      <name>roleDisplayNameAttributeID</name>
      <value>cn</value>
   </option>
   <option>
      <name>membershipAttributeID</name>
      <value>member</value>
   </option>
   <option>
      <name>membershipAttributeIsDN</name>
      <value>true</value>
   </option>
</option-group>
<option-group>
   <group-name>userCreateAttibutes</group-name>
   <option>
      <name>objectClass</name>
      <value>top</value>
      <value>uidObject</value>
      <value>person</value>
      <value>inetUser</value>
   </option>
   <!--Schema requires those to have initial value-->
   <option>
      <name>cn</name>
      <value>none</value>
   </option>
   <option>
      <name>sn</name>
      <value>none</value>
   </option>
</option-group>

UserProfileModule has additional configuration file that defines user properties. It is specified in configuration in:

         
       <module>
         <type>UserProfile</type>
         <implementation>DELEGATING</implementation>

         (...)

         <config>

            (...)

            <option>
               <name>profileConfigFile</name>
               <value>conf/identity/profile-config.xml</value>
            </option>
         </config>
      </module>
         
      

This means that you can configure user profile in jboss-portal.sar/conf/identity/profile-config.xml

           
<profile>

   <property>
      <name>user.name.nickName</name>
      <type>java.lang.String</type>
      <access-mode>read-only</access-mode>
      <usage>mandatory</usage>
      <display-name xml:lang="en">Name</display-name>
      <description xml:lang="en">The user name</description>
      <mapping>
         <database>
            <type>column</type>
            <value>jbp_uname</value>
         </database>
      </mapping>
   </property>

   <property>
      <name>user.business-info.online.email</name>
      <type>java.lang.String</type>
      <access-mode>read-write</access-mode>
      <usage>mandatory</usage>
      <display-name xml:lang="en">Email</display-name>
      <description xml:lang="en">The user real email</description>
      <mapping>
         <database>
            <type>column</type>
            <value>jbp_realemail</value>
         </database>
         <ldap>
            <value>mail</value>
         </ldap>
      </mapping>
   </property>

   <property>
      <name>portal.user.location</name>
      <type>java.lang.String</type>
      <access-mode>read-write</access-mode>
      <usage>optional</usage>
      <display-name xml:lang="en">Location</display-name>
      <description xml:lang="en">The user location</description>
      <mapping>
         <database>
            <type>dynamic</type>
            <value>portal.user.location</value>
         </database>
      </mapping>
   </property>

   (...)

</properties>
           
        

Configuration file contains properties definition that can be retrieved using the PropertyInfo interface. Each property used in portal has to be defined here.

Delegating UserProfileModule implementation has very specific role. When we use a storage mechanism like LDAP we may not be able to map all user properties into LDAP attributes because of schema limitations. To solve this problem we still can use the database to store user properties that do not exist in the LDAP schema. The Delegating user profile module will recognize if a property is mapped as ldap or database and delegate setProperty()/getProperty() method invocation to proper module implementation. This is implemented in org.jboss.portal.identity.DelegatingUserProfileModuleImpl. If property is mapped either as ldap and database the ldap mapping will have higher priority.

            
<module>
   <!--type used to correctly map in IdentityContext registry-->
   <type>UserProfile</type>
   <implementation>DELEGATING</implementation>

   <!--name of service and class for creating mbean-->
   <service-name>portal:service=Module,type=UserProfile</service-name>
   <class>org.jboss.portal.identity.DelegatingUserProfileModuleImpl</class>
   <!--set of options that are set in instantiated object-->
   <config>
      <option>
         <name>jNDIName</name>
         <value>java:/portal/UserProfileModule</value>
      </option>
      <option>
         <name>dbModuleJNDIName</name>
         <value>java:/portal/DBUserProfileModule</value>
      </option>
      <option>
         <name>profileConfigFile</name>
         <value>conf/identity/profile-config.xml</value>
      </option>
   </config>
</module>
         

Module options are:

Because of the behavior described in the previous section, database UserProfileModule requires some special features. If a user is present in LDAP server but a writable property isn't mapped as an LDAP attribute, such property requires to be stored in the database. In order to achieve such result the user need to be synchronized from LDAP into the database first.

Class org.jboss.portal.identity.db.HibernateUserProfileModuleImpl has additional synchronization features. Here are the options: