Leveraging the IBM Tivoli Identity Manager's (ITIM) self-care provisioning functionality from a Struts JSR168 Portlet using the ITIM API

Many IT Infrastructures today use IBM® Tivoli® Identity Manager (ITIM) to real-time provision user profile (self- care) details to its diverse datastores and other systems. If your requirements are to leverage the ITIM self-care provisioning functionality from within your customized business portal running on IBM WebSphere® Portal Server (WPS), this article shows you how. This article, with an accompanying downloadable example, discusses how a Struts JSR168 Portlet running on WPS can leverage the ITIM self-care provisioning functionality using the ITIM API.

Share:

Kapil Lele (kapil_lele@yahoo.com), Product Specialist (Technical Architect), Synergy Plus Pty. Ltd.

Kapil LeleKapil Lele has 8 years of global IT experience working in USA, Canada, and Australia extensively with IBM Software. His experience spans a diversity of industries including Financial Services, Utilities, Health Services, and Government. He currently works as a Product Specialist (Technical Architect) for Synergy Plus Pty. Ltd. specializing in architecting, /designing, and/ developing corporate security solutions using the Tivoli Security Software Suite and WebSphere Portal for Synergy's clients. Synergy Plus, based in Melbourne, Australia, is IBM's primary business Business partner Partner in Australia. It is leading the growth of the Tivoli Security space in Australia.



26 March 2007

What is a Struts JSR168 Portlet?

The JSR168 Portlet specification is a standard API for developing portlets supported by multiple portal vendors such as IBM, Sun, Weblogic, and so on. Portlet interoperability is ensured when deployed to the portlet containers of vendors supporting JSR168.

Apache Struts is the most widely used application development framework across the industry. IBM formerly provided a Struts Portlet Framework to enable development of proprietary IBM Portlet API-compliant Struts portlets. With the advent of JSR168, IBM extended its proprietary Struts Portlet Framework to facilitate development of industry standard JSR168 Portlet API-compliant Struts portlets.

This article does not discuss Struts, JSR168, or how to create Struts JSR168 Portlets. For information on these topics, please refer to links in the Resources section of this article. This article describes how a Struts JSR168 Portlet can use the ITIM API to leverage the ITIM self care provisioning functionality from within WPS.


What is ITIM?

The IBM Tivoli Security Software Suite currently provides a corporate security solution for IT infrastructures of small, medium, and large businesses. The security domain managed by the Tivoli Security Software Suite encompasses most systems of an IT infrastructure including application servers, datastores, other systems, and realizes a Single Sign-On solution within the security domain.

ITIM provides centralized user identity (user identification) and self-care (password and other profile information) management functionality. ITIM supports provisioning of this functionality to diverse datastores and other systems. Provisioning results in the creation of an account (combination of ITIM user identity and access control group in provisioned system), which can be subsequently reconciled into and referenced from within ITIM.

User identity and self-care management functionality is implemented within ITIM as security services conforming to a Service Oriented Architecture (SOA). These security services can be fully configured using the ITIM native user interface or leveraged through ITIM APIs using customized user interfaces of Web and portlet applications.

Figure 1. ITIM APIs customized user interfaces versus ITIM native user interface
Figure 1. ITIM APIs customized user interfaces versus ITIM native user interface

From Figure 1, an IT infrastructure leverages the ITIM APIs using customized user interfaces primarily for the following reasons:

  1. Customize access to the ITIM security services within the IT infrastructure's business process flow as part of business process integration.
  2. The IT infrastructure's business applications incorporating extensive internationalization and site-specific branding are better suited to leverage the ITIM security services from APIs using customized user interfaces rather than the ITIM native user interface.

This article specifically illustrates how the user password and profile aspects of the ITIM self- care security service can be leveraged by a Struts JSR168 Portlet application using the ITIM APIs. The article also discusses how the Struts JSR168 Portlet uses the ITIM APIs to trigger ITIM to real-time provision the user password and profile information to WPS, resulting in the creation of ITIM WPS accounts. The ITIM WPS accounts are created in the WPS LDAP schema of the LDAP directory. The LDAP directory hosting both, the WPS LDAP schema,and as well as the ITIM LDAP schema used for this example is IBM Tivoli Directory Server (ITDS). Please note that configuration of ITIM provisioning policies in order to enable real-time provisioning to WPS by ITIM is not within the scope of this article. Hence, this article assumes that the reader already has an existing ITIM and /WPS environment to deploy the Struts JSR168 Portlet to. Change Password and Change Profile use cases are implemented by the deployable Struts JSR168 Portlet (contained within the StrutsJSR168Portlet_ITIMAPI_v1.0.0.zip archive), which can be found in the Downloads section of this article.

For more detailed information on ITIM, please refer to links in the Resources section of this article.


Introduction to the ITIM API

A representative sample of ITIM API classes and interfaces illustrating ITIM API behavior and state can be logically organized into the following process flow in Figure 2:

Figure 2. ITIM API classes and interfaces
Figure 2. ITIM API classes and interfaces

The ITIM API classes and interfaces shown in Figure 2 are specifically used in the example Struts JSR168 Portlet code accompanying this article. To browse the entire ITIM API, please refer to the 'ITIM Applications API' link in the Resources section of this article.

Understanding ITIM API behavior and state can be abstracted as follows:

  1. ITIM API PlatformContext related classes and interfaces are used to establish communication between an application (in our case the Struts JSR168 Portlet) and ITIM.
  2. Once communication is established, the PlatformContext related classes and interfaces facilitate the creation and retrieval of ITIM API 'Manager' related objects, which are responsible for managing the lifecycle of ITIM API 'ManagedObjects'.
  3. ITIM API 'ManagedObjects' represent and store the ITIM entities to be managed called ITIM API 'ValueObjects'.
  4. ITIM API 'ValueObjects' use ITIM API utility class 'AttributeValue' objects to store attribute information of ITIM entities. Attribute information includes user identity (user identification) and self-care (password and other profile information) stored in ITIM 'Person' objects representing ITIM Persons and possibly in ITIM 'Account' objects representing ITIM Accounts belonging to ITIM Persons, which in turn are provisioned to an IT infrastructure's diverse datastores and other systems. Additionally, an ITIM Person's organizational attribute information is stored in ITIM 'OrganizationalUnit' objects.

The above abstraction of understanding ITIM API behavior and state is contextualized in detail in the 'Design and Implementation of the Solution' section of this article using the Struts JSR168 Portlet code corresponding to the Change Password and Change Profile use cases.

Please note that though the ITIM API RequestManager and Request objects are not used in the example Struts JSR168 Portlet, they are important to mention as they facilitate asynchronous managed communication of all the ITIM Manager, ManagedObjects, and ValueObjects between the application (in our case the Struts JSR168 Portlet) and ITIM. This results in a significant performance benefit to an IT infrastructure's custom applications using the ITIM API.

For further details about the ITIM API, please refer to links in the Resources section of this article.


Design and implementation of the solution

The UML class diagram in Figure 3 illustrates the design of classes and interfaces used to implement the Change Password and Change Profile use cases.

Figure 3. Struts JSR168 Portlet class diagram
Figure 3. Struts JSR168 Portlet class diagram

The classes and interfaces shown in Figure 3 can be described as follows:

Common

com.sonicservices.tivoli.common.plugins.InitializationPlugin:

This class implements the Struts Framework Plug-in interface. InitializationPlugin is loaded upon startup of the Struts JSR168 Portlet and is used to initialize application utilities such as Logging (in our case log4j) and establish communication between the Struts JSR168 Portlet and ITIM system.

Methods of this class are:

  1. Initialize Logging Utility (log4j):
    Please refer to the initializeLogging(ActionServlet actionServlet) method code.
    The log4j PropertyConfigurator reads the log4j.properties file and initializes the log4j logging utility in the following code:
    PropertyConfigurator.configure(prefix+this.loggerConfig);

    The location of the log4j.properties file is provided to the InitializationPlugin class by the Struts Framework in the loggerConfig field from the following code specified in the struts-config.xml file:

    <set-property property="loggerConfig" value="/WEB-INF/classes/com/sonicservices/tivoli /resources/log4j.properties"/>
  2. Load your existing ITIM environment specific properties into memory (Hashmap), which is used by the MyTivoliIdentityManager Singleton class to establish application communication with ITIM:
    Please refer to the initializeProperties() method code.

    Your existing ITIM environment specific properties file (tivolisecurity.properties) is read using standard Java™ I/O classes The corresponding property-value pairs are placed into the tivoliSecurityPropertiesHashMap.

    The location of the tivolisecurity.properties file is provided to the InitializationPlugin class by the Struts Framework in the tivoliConfig field from the following code specified in the struts-config.xml file:

    <set-property property="tivoliConfig" value="/WEB-INF/classes/com/sonicservices/tivoli /resources/tivolisecurity.properties"/>

    Please note that you will need to customize the included com/sonicservices/Tivoli/resources/tivolisecurity.properties file with property-value pairs specific to your ITIM environment.

  3. Load the MyTivoliIdentityManager Singleton into memory for use by application communication with ITIM using the ITIM API.
    Please refer to the initializeTivoliSecurity() method code.

    The InitializationPlugin class provides the MyTivoliIdentityManager class with the tivoliSecurityPropertiesHashMap in order to construct and load the MyTivoliIdentityManager Singleton into memory, which as part of construction, establishes application communication with ITIM in the following code:

    MyTivoliIdentityManager.prepareInstance(tivoliSecurityPropertiesHashMap);

com.sonicservices.tivoli.common.utilities.MyTivoliIdentityManager:

This Singleton Broker class encapsulates logic for the Struts JSR168 Portlet to communicate with ITIM and to manage the lifecycle of ITIM Manager and ManagedObjects used by the Struts JSR168 Portlet.

Methods of this class are:

  1. Construct and load the MyTivoliIdentityManager Singleton into memory establishing application communication with ITIM during construction.
    Please refer to the MyTivoliIdentityManager(PlatformContext platformContext,Subject subject,HashMap tivoliSecurityPropertiesHashMap) constructor, getInstance(), prepareInstance(HashMap tivoliSecurityPropertiesHashMap), and configureInstance(HashMap tivoliSecurityPropertiesHashMap) method code.
    The following code in the configureInstance method is used to establish application communication with ITIM using the PlatformContext related classes and interfaces of the ITIM API:
    a.
    Hashtable env = new Hashtable();
    env.put(InitialPlatformContext.CONTEXT_FACTORY, (String)tivoliSecurityPropertiesHashMap.
                                                    get("platformContextFactory"));
    env.put(PlatformContext.PLATFORM_URL, (String)tivoliSecurityPropertiesHashMap.
                                          get("platform.url"));
    env.put(PlatformContext.PLATFORM_PRINCIPAL, (String)tivoliSecurityPropertiesHashMap.
                                                get("platform.principal"));
    env.put(PlatformContext.PLATFORM_CREDENTIALS, (String)tivoliSecurityPropertiesHashMap.
                                                  get("platform.credentials"));
    
    PlatformContext platformContext = new InitialPlatformContext(env);

    A new ITIM InitialPlatformContext object is instantiated that consists of connection information to ITIM obtained from the tivoliSecurityPropertiesHashMap (tivolisecurity.properties). In the ITIM environment used for this example, the following property-value pairs yield this connection information.

    platformContextFactory=com.ibm.itim.apps.impl.websphere.WebSpherePlatformContextFactory
    platform.url=iiop://localhost:2809
    platform.principal=wasadmin
    platform.credentials=wasadmin
    b.
    PlatformCallbackHandler handler = new PlatformCallbackHandler(
                                          (String)tivoliSecurityPropertiesHashMap.
                                          get("platform.itimuser"), 
                                          (String)tivoliSecurityPropertiesHashMap.
                                          get("platform.itimpassword"));
    handler.setPlatformContext(platformContext);

    A new PlatformCallbackHandler object is instantiated, which consists of ITIM security credentials (ITIM userId and password) obtained from the tivoliSecurityPropertiesHashMap (tivolisecurity.properties) with authentication access to ITIM. Also, the PlatformCallbackHandler is associated with the InitialPlatformContext from Step a. The PlatformCallbackHandler is the ITIM implementation of the standard Java Authentication and Authorization Service (JAAS) CallbackHandler interface. In the ITIM environment used for this example, the following property-value pairs yield the security credentials:

    platform.itimuser=itimadmin
    platform.itimpassword=itimadmin
    c.
    LoginContext loginContext = new LoginContext((String)
                    tivoliSecurityPropertiesHashMap.get("loginContext"), handler);
    loginContext.login();
    
    Subject subject = loginContext.getSubject();
    
    instance = new MyTivoliIdentityManager(platformContext,subject,
                                                 tivoliSecurityPropertiesHashMap);

    Finally, a new LoginContext object is instantiated from the value of the ITIM LoginContext property (default is "ITIM") obtained from the tivoliSecurityPropertiesHashMap (tivolisecurity.properties) and the PlatformCallbackHandler from Step b. The ITIM LoginContext property corresponds to the JAAS login setting in the IBM WebSphere Application Server (WAS) hosting the ITIM system. Please refer to Step 3 of the 'Configuration of the Solution in an Existing ITIM/WPS Environment' section of this article for details on how to validate the JAAS login setting in WAS. The new LoginContext then initiates authentication (login) to the ITIM system. A successful authentication results in the availability of an ITIM Subject object.

    The ITIM Subject together with the ITIM InitialPlatformContext object instantiated in Step a are initialized members of the MyTivoliIdentityManager Singleton during instantiation. These important ITIM objects are subsequently accessed by the application from the MyTivoliIdentityManager Singleton for instantiation, /storage, and /retrieval of the various ITIM Manager and ManagedObjects by the application from ITIM.

  2. Instantiate ITIM API Manager related objects used by the application to manage ITIM API ManagedObjects (representing ITIM entities such as Person, Account, OrganizationalUnit etc.) retrieved from and communicated to the ITIM system.

    Please refer to the getPersonManager(), getPasswordManager(), and getAccountManager() method code.

    It is easy to discern from the method code that instantiation of the Manager-related objects requires the ITIM Subject and ITIM InitialPlatformContext objects instantiated earlier.

  3. Instantiate the SearchMO ITIM API ManagedObject, which is then used by the application to retrieve OrganizationalUnit entities previously created in the ITIM system. In the ITIM system used for this article, only one OrganizationalUnit entity was configured. The OrganizationalUnit entity is then encapsulated in a newly instantiated OrganizationalContainerMO ITIM API ManagedObject for use within the application.

    Please refer to the getSearchMO() and getOrganizationalContainerMO() method code.
    A new SearchMO ITIM API ManagedObject is instantiated using the ITIM Subject and ITIM InitialPlatformContext objects in the following code.
    searchMO = new SearchMO(platformContext, subject);

    The SearchMO object is then used to retrieve the OrganizationalUnit entity previously configured in the ITIM system, followed by the instantiation of a new OrganizationalContainerMO ITIM API ManagedObject.

    a.
    searchMO.setCategory(ObjectProfileCategory.CONTAINER);

    ITIM API OrganizationalUnit entities are categorized as Containers in the ITIM system, which is indicated as the search category.
    b.
    searchMO.setContext(new CompoundDN(new DistinguishedName(
                       (String)tivoliSecurityPropertiesHashMap.get("tenantdn"))));

    Setting the search context indicates the LDAP Distinguished Name (DN) in the ITIM LDAP schema used as the starting point to search for the ITIM OrganizationalUnit entity.

    The ITIM LDAP DN is obtained from the tivoliSecurityPropertiesHashMap (tivolisecurity.properties). In the ITIM environment used for this example, the following property-value pair yields this information:

    tenantdn=ou=SonicSvcs,dc=com
    c.
    searchMO.setProfileName(ObjectProfileCategoryConstant.ORGUNIT);

    Amongst the ITIM Containers, the ITIM entity of interest is OrganizationalUnit, which is indicated as the search profilename.
    d.
    searchMO.setScope(SearchMO.SUBTREE_SCOPE);

    The search scope is set to all LDAP nodes at the same level and below the ITIM LDAP DN specified in Step b above.
    e.
    searchMO.setFilter("(ou=" + (String)tivoliSecurityPropertiesHashMap.
                                        get("organizationalUnitName") + ")");

    The search filter further narrows the search scope. It is set to retrieve the ITIM OrganizationalUnit entity with a particular organizational unit name.

    The organizational unit name is obtained from the tivoliSecurityPropertiesHashMap (tivolisecurity.properties). In the ITIM environment used for this example, the following property-value pair yields this information.

    organizationalUnitName=SonicSecurities
    f.
    Collection containers = searchMO.execute().getResults();
    
    if (containers == null || containers.isEmpty()) {
    throw new ApplicationException("Organizational Unit not found in ITIM");
    }
    
    OrganizationalUnit organizationalUnit = (OrganizationalUnit)containers.iterator().next();

    The search is executed and the resulting Collection (Java API) of ITIM Containers retrieved from the ITIM system yields the ITIM OrganizationalUnit entity of interest.
    g.
    organizationalContainerMO = new OrganizationalContainerMO(platformContext, subject, 
                                                   organizationalUnit.getDistinguishedName());

    A new OrganizationalContainerMO ManagedObject is instantiated for use within the application using the OrganizationalUnit entity retrieved in Step f above, the ITIM Subject, and the ITIM InitialPlatformContext objects.

com.sonicservices.tivoli.common.actions.BaseAction:

This class extends the IBM Struts Portlet Framework StrutsAction class. All Change Profile and Change Password related Struts Action classes extend BaseAction. Through inheritance, BaseAction captures common functionality, which is afforded to all its derived Struts Action classes through inheritance.

Methods of this class are:

  1. 1. Retrieve user identity (user identification), that is i.e. UserId from the PortletRequest, either by previously successfully authenticating to WebSeal or to WPS. Based on the UserId, use the ITIM API PersonManager object to retrieve the PersonMO ManagedObject from the ITIM system and store it in PortletSession to be used by the application.


    a.
    MyTivoliIdentityManager myTivoliIdentityManager = MyTivoliIdentityManager.getInstance();

    Obtain the MyTivoliIdentityManager Singleton previously instantiated upon application startup.

    b.
    myTivoliIdentityManager.getPersonManager().getPeople("uid", request.getRemoteUser(), 
                                    myTivoliIdentityManager.getOrganizationalContainerMO());
    
    request.getPortletSession().setAttribute("personMO",(PersonMO)people.iterator().next());

    Obtain a newly instantiated or previously instantiated ITIM API PersonManager object, which in turn retrieves from the ITIM system the ITIM API PersonMO ManagedObject representing the ITIM Person entity corresponding to the UserId obtained from the PortletRequest. The PersonMO ManagedObject is then stored in PortletSession for use by the application. Notice that a newly instantiated or previously instantiated ITIM API OrganizationalContainerMO ManagedObject representing the ITIM OrganizationalUnit entity containing the ITIM Person entity is also passed as a parameter to the PersonManager getPeople() method.

  2. Retrieve the PersonMO ManagedObject from PortletSession when required for use within the application.
    Please refer to the getPersonMO(PortletRequest request) method code.
    a.
    personMO = (PersonMO)session.getAttribute("personMO");

    The PersonMO ManagedObject representing the ITIM Person entity is retrieved from the PortletSession into which it was previously stored for use by the application.

Change password use case

The Change Password use case can be summarized by the sequence diagram in Figure 4.

Figure 4. Change Password use case sequence diagram
Figure 4. Change Password use case sequence diagram

com.sonicservices.tivoli.changepassword.actions.EditChangePasswordAction:

This Struts Action class is used to initialize, set up, and prepare self-care (password) data to be displayed in form (com.sonicservices.tivoli.changepassword.forms.ChangePasswordFormBean) fields on the Change Password screen (/jsp/changepassword/changePassword.jsp).

Methods of this class are:

  1. Please refer to the execute(ActionMapping mapping, ActionForm form, PortletRequest request, PortletResponse response) method code.
    a.
    setPersonMO(request);

    Because this Action class is called upon initial entry into the ChangePassword functionality (Usecase) of the Struts JSR168 Portlet, an initial call is made to the BaseAction class to set the ITIM API PersonMO ManagedObject retrieved from the ITIM system into PortletSession.

    b.
    changePasswordForm.setUserId(getPersonMO(request).getData().getAttribute("uid").
                                                                            getString());

    Set the UserId attribute retrieved from the ITIM Person entity represented by the ITIM PersonMO ManagedObject into the Struts FormBean ChangePasswordFormBean to be displayed on the Change Password screen.

com.sonicservices.tivoli.changepassword.actions.ChangePasswordAction:

This Struts Action class is used to communicate self- care (password) data, which was changed on the Change Password screen to ITIM using the ITIM API. Subsequently, based on provisioning policies configured (not included within the scope of this article) within your existing ITIM and /WPS environment, ITIM will provision the updated ITIM Person's self- care (password) data to the LDAP directory backing WPS. Provisioning results in the updating of the ITIM Person's WPS account (combination of ITIM user identity and WPS group), which can be subsequently reconciled into and referenced from within ITIM.

Methods of this class are:

  1. Please refer to the execute(ActionMapping mapping, ActionForm form, PortletRequest request, PortletResponse response) method code.
    a.
    MyTivoliIdentityManager myTivoliIdentityManager = MyTivoliIdentityManager.getInstance();

    Obtain the MyTivoliIdentityManager Singleton instance previously instantiated upon application startup.

    b.
    myTivoliIdentityManager.getPasswordManager().synchPasswords(getPersonMO(request),
                                            changePasswordForm.getNewPassword(),new Date());

    Obtain a newly instantiated or previously instantiated ITIM API PasswordManager Manager object and invoke its synchPasswords() method. The synchPasswords() method retrieves all accounts belonging to the ITIM Person passed as a parameter to this method and updates ashe accounts with the new password entered on the Change Password screen and which is also passed in as a parameter to the synchPasswords() method. Retrieval and updating is done synchronously in one step. The third parameter passed to the synchPasswords() method specifies when the ITIM system should schedule the password change. Values of new Date() and null equivalently imply schedule with immediate effect.

    Instead of synchronously, if you first need to make certain changes to an ITIM Person's accounts prior to updating the new password to the accounts, that is retrieval and updating in two distinct steps, the following alternative chain of ITIM API Change Password related calls can be used:

    i.
    PasswordManager passwordManager = myTivoliIdentityManager.getPasswordManager();

    Obtain a newly instantiated or previously instantiated ITIM API PasswordManager Manager object.

    ii.
    Collection accountMOs = passwordManager.getPasswordAccounts(getPersonMO(request));

    Invoke the getPasswordAccounts() method to retrieve all the ITIM Person's accounts as a Java Collection. Make changes to the accounts as required by your business.

    iii.
    passwordManager.changePassword(accountMOs,changePasswordForm.getNewPassword(),
                                                                    new Date(),false);

    Invoke the changePassword() method,passing as parameters the Collection of accounts, the new password entered on the Change Password screen, Scheduling Date-Time, and finally a true/false parameter indicating whether the ITIM system should send a notification to the User (ITIM Person) of the password change.

    Another IBM developerWorks article referenced by the link 'Introduction to developing with Tivoli Identity Manager API's', which can be found in the Resources section of this article, also discusses the Change Password use case.

Change Profile use case

The Change Profile use case can be summarized by the sequence diagram in Figure 5.

Figure 5. Change Profile use case sequence diagram
Figure 5. Change Profile use case sequence diagram

com.sonicservices.tivoli.changeprofile.actions.EditChangeProfileAction

This Struts Action class is used to initialize, set up, and prepare self-care (profile) data to be displayed in form (com.sonicservices.tivoli.changeprofile.forms.ChangeProfileFormBean) fields on the Change Profile screen (/jsp/changeprofile/changeProfile.jsp).

Methods of this class are:

  1. Please refer to the execute(ActionMapping mapping, ActionForm form, PortletRequest request, PortletResponse response) method code.
    a.
    setPersonMO(request);

    Since this Action class is called upon initial entry into the ChangeProfile functionality (use case) of the Struts JSR168 Portlet, an initial call is made to the BaseAction class to set the ITIM API PersonMO ManagedObject retrieved from the ITIM system into PortletSession.

    b.
    changeProfileForm.setUserId(personMO.getData().getAttribute("uid").getString());
    changeProfileForm.setFirstName(personMO.getData().getAttribute("givenname").getString());
    changeProfileForm.setLastName(personMO.getData().getAttribute("sn").getString());
    if (personMO.getData().getAttribute("mail") != null) {
        changeProfileForm.setMail(personMO.getData().getAttribute("mail").getString());

    Set the UserId, First Name, Last Name, and Email Address attributes retrieved from the ITIM Person entity represented by the ITIM PersonMO ManagedObject into the Struts FormBean ChangeProfileFormBean to be displayed on the Change Profile screen.

com.sonicservices.tivoli.changeprofile.actions.ChangeProfileAction

This Struts Action class is used to communicate self- care (profile) data, which was changed on the Change Profile screen to ITIM using the ITIM API. Subsequently, based on the default (out-of-the-box) configured ITIM provisioning policy, the changed self- care (profile) data is provisioned to the ITIM Person's account in the ITIM LDAP schema in the LDAP directory. Also, based on customized provisioning policies configured (not included within the scope of this article) within your existing ITIM and /WPS environment, ITIM will provision the changed self- care (profile) data to the ITIM Person's WPS account (combination of ITIM user identity and WPS group) in the WPS LDAP schema in the LDAP directory.

Methods of this class are:

  1. 1. Please refer to the execute(ActionMapping mapping, ActionForm form, PortletRequest request, PortletResponse response) method code.
    An ITIM Person's self-care (profile) data changed on the Change Profile screen is communicated to the ITIM system twice (in two distinct steps):
    a.

    Update the ITIM Person's account in the ITIM system, that is, the ITIM LDAP schema in the LDAP directory. This step is based on the default configured ITIM provisioning policy in the ITIM system.

    i.
    MyTivoliIdentityManager myTivoliIdentityManager = MyTivoliIdentityManager.getInstance();

    Obtain the MyTivoliIdentityManager Singleton instance previously instantiated upon application startup.

    ii.
    PersonMO personMO = getPersonMO(request);
    Person person = personMO.getData();

    Obtain the previously instantiated ITIM API PersonMO ManagedObject from PortletSession. Then obtain the instance of the ITIM API Person entity represented by the PersonMO object.

    iii.
    AttributeValue personAttributeValueFirstName = new AttributeValue("givenname",
                                                        changeProfileForm.getFirstName());
    person.setAttribute(personAttributeValueFirstName);

    Instantiate a new ITIM API AttributeValue utility object storing in it the ITIM Person's 'first name' self- care (profile) value changed on the Change Profile screen. Then update the ITIM API Person entity with the AttributeValue utility object.

    iv.
    personMO.update(person, new Date());

    Finally, after updating the ITIM API Person entity with AttributeValue utility objects containing all the self- care (profile) values changed on the Change Profile screen, store the updated ITIM Person object into the ITIM PersonMO object. The update() method of the ITIM PersonMO object then communicates the ITIM Person entity to the ITIM system. The second parameter to the update() method is a scheduling parameter, which, in the case of new Date() (or equivalently null), instructs the ITIM system to provision the changed self- care (profile) attributes (stored in the ITIM Person entity) to the ITIM Person's account in the ITIM system, that is i.e. the ITIM LDAP schema in the LDAP directory, with immediate effect.



    b.

    Update the ITIM Person's account in the WPS system, that is i.e., the WPS LDAP schema in the LDAP directory. This step is based on customized provisioning policies configured (not included within the scope of this article) within your existing ITIM and /WPS environment.

    i.
    AccountManager accountManager = myTivoliIdentityManager.getAccountManager();

    Obtain the newly instantiated or previously instantiated ITIM API AccountManager Manager object.

    ii.
    Collection accounts = accountManager.getAccounts(personMO,null);
    AccountMO accountMO = (AccountMO)accounts.iterator().next();
    //Now set the modified attributes from ChangeProfile FormBean into the retrieved 
    //ITIM (Portal and TAM) Account
    Account account = accountMO.getData();

    From the AccountManager object, obtain the ITIM Person's (represented by PersonMO passed as a parameter to getAccounts) WPS account represented by an ITIM API AccountMO ManagedObject. Iterating to the first value in the Java Collections API Iterator provides this AccountMO object. Finally, the ITIM API Account entity associated to the ITIM Person is obtained from the AccountMO object's getData() method.

    iii.
    AttributeValue accountAttributeValueFirstName = new AttributeValue("firstname",
                                                       changeProfileForm.getFirstName());
    account.setAttribute(accountAttributeValueFirstName);

    Instantiate a new ITIM API AttributeValue utility object storing in it the ITIM Person's 'first name' self-care (profile) value changed on the Change Profile screen. Then update the ITIM API Account entity with the AttributeValue utility object.

    iv.
    accountMO.update(account,new Date());

    Finally, after updating the ITIM API Account entity with AttributeValue utility objects containing all the self-care (profile) values changed on the Change Profile screen, store the updated ITIM Account object into the ITIM AccountMO object. The update() method of the ITIM AccountMO object then communicates the ITIM Person's Account entity to the ITIM system. The second parameter to the update() method is a scheduling parameter, which, in the case of new Date() (or equivalently null), instructs the ITIM system to provision the changed self-care (profile) attributes (stored in the ITIM Account entity) to the ITIM Person's account in the WPS system, that is,the WPS LDAP schema in the LDAP directory with immediate effect. Provisioning is based on customized provisioning policies configured (not included within the scope of this article) within your existing ITIM and WPS environment.

    Please note that the IBM Struts Portlet Framework and Struts Framework related classes and interfaces Plug-in, StrutsAction, ValidatorActionForm, ChangePasswordFormBean, and ChangeProfileFormBean are not described in detail above, because they do not use the ITIM API and the focus of the article is on the use of the ITIM API.

    To learn more about UML class diagrams, please refer to the 'Practical UML - A Hands-On Introduction for Developers' link in the Resources section of this article.


Configuration of the Solution solution in an Existing existing ITIM and /WPS Environmentenvironment

An assumption to a successful configuration of the solution in an existing ITIM and WPS environment is network connectivity existing between physical servers hosting WAS, the ITIM system, WPS, and the LDAP backing store.

The Struts JSR168 Portlet consisting of Change Password and Change Profile functionality (use cases) is configured into an existing ITIM/WPS environment as follows:

  1. Configure the Struts JSR168 Portlet to interface with ITIM.
    a.
    The Struts JSR168 Portlet should contain the following ITIM API specific jar files in order to be able to leverage the ITIM API:
    i.  itim_api.jar, and
    ii. api_ejb.jar

    In the example Struts JSR168 Portlet accompanying this article, these jar files can be found in the WebContent/WEB-INF/lib directory.

    b.

    WAS contains a default 'was.policy' file in the >>WAS install root<</properties directory. This default was.policy file specifies permission rules allowing all enterprise applications hosted by WAS special access to internal WAS container resources such as the WAS JAAS implementation, and so on. By default, no permissions for special access are granted. However, individual enterprise applications can override the default was.policy permission rules by using their own was.policy files. The Struts JSR168 Portlet contains its own was.policy file, which is in the WebContent/META-INF directory of the example Struts JSR168 Portlet accompanying this article and has the following permission rule granting the portlet full permissions to internal WAS container resources such as the WAS JAAS implementation, and so on.

    grant codeBase "file:${application}" {
    permission java.security.AllPermission;
    };

    This is required when the Struts JSR168 Portlet's MyTivoliIdentityManager Singleton uses JAAS to authenticate to the ITIM system in order to establish a connection between the Struts JSR168 Portlet and ITIM.

    c.

    ITIM uses the WAS JAAS implementation as its authentication mechanism, that is, for applications to authenticate and login to ITIM. In order for ITIM to use the WAS JAAS implementation, the following configuration property is specified in the WAS wsjaas.conf file in the <<WAS install root>>/properties directory:

    ITIM {
        com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy required 
                         delegate=com.ibm.itim.apps.jaas.spi.PlatformLoginModule;
    };

    The above 'ITIM' property is used by the Struts JSR168 Portlet to authenticate to ITIM and can be viewed using the WAS Admin Console associated with the WAS instance hosting the ITIM system, as shown in screenshots captured in the 'Configuration_of_the_Solution_Screenshots.pdf'

    For information on how to create Struts JSR168 Portlet deployable artifacts, please refer to the 'IBM Rational Application Developer Online InfoCenter' link in the Resources section of this article.

  2. Deploy/Install the Struts JSR168 Portlet in WPS:
    a.

    Copy the Struts JSR168 Portlet deployable artifact 'TivoliWpsStrutsPortlet.war' into the <<WPS install root>>/installableApps directory as shown in a screenshot captured in the 'Configuration_of_the_Solution_Screenshots.pdf' document, a link to which, can be found in the Downloads section of this article.

    For information on how to create Struts JSR168 Portlet deployable artifacts, please refer to the 'IBM Rational Application Developer Online InfoCenter' link in the Resources section of this article.

    b.

    Login to the WPS Administration Console using the WPS Administrator user ID and password (userid 'wpsadmin' and password 'wpsadmin' used in this example) configured in your WPS environment and install the 'TivoliWpsStrutsPortlet.war', as shown in screenshots captured in the 'Configuration_of_the_Solution_Screenshots.pdf' document, which is linked to in the Downloads section of this article.

    c.

    Create a new WPS Page (called TivoliSecurityTesting in this example) as shown in a screenshot captured in the 'Configuration_of_the_Solution_Screenshots.pdf' document, which is linked to in the Downloads section of this article.

    d.

    Configure authorization for existing ITIM Persons with WPS accounts to access the new WPS Page (TivoliSecurityTesting) as shown in screenshots captured in the 'Configuration_of_the_Solution_Screenshots.pdf' document, which is linked to in the Downloads section of this article.

    e.

    Configure the new WPS Page to host the 'TivoliWpsStrutsPortlet.war' (Struts JSR168 Portlet) as shown in screenshots captured in the 'Configuration_of_the_Solution_Screenshots.pdf' document, which is linked to in the Downloads section of this article.

    f.

    Configure authorization for existing ITIM Persons with WPS accounts to access the Struts JSR168 Portlet as shown in screenshots captured in the 'Configuration_of_the_Solution_Screenshots.pdf' document, which is linked to in the Downloads section of this article.

    g.

    Just to confirm successful deployment and installation of the Struts JSR168 Portlet in WPS, logout of the WPS Administration Console and restart both WPS and WAS. Then log in to the WPS Administration Console using your WPS Administrator user ID and password. Navigate to your WPS Page created in Step c above where you should see the Landing (Menu) Screen of the Struts JSR168 Portlet as shown in a screenshot captured in the 'Configuration_of_the_Solution_Screenshots.pdf' document, which is linked to in the Downloads section of this article.

    Please note that the above Configuration Steps of this article do not include installation or configuration of an ITIM environment including customized ITIM provisioning policies to provision an ITIM Person's account to a WPS system, that is, the WPS LDAP schema in the LDAP directory. Nor do the \Configuration Steps include installation or configuration of WPS. For details on these subjects, please refer to links in the Resources section of this article.

    Please refer to the example Struts JSR168 Portlet (contained within the StrutsJSR168Portlet_ITIMAPI_v1.0.0.zip archive), which are in the Downloads section of this article for all portlet specific configuration resources previously discussed in the 'Configuration of the Solution in an Existing ITIM/WPS Environment' section.


Using the solution

Log into WPS using an existing ITIM Person with a WPS account. In this example, the existing ITIM Person is 'Sharon Stone' as shown in the following screenshot of the ITIM Administration Console in Figure 6:.

Figure 6. ITIM administration console
Figure 6. ITIM administration console

ITIM Person 'Sharon Stone's' existing ITIM account with user ID 'sstone' and password 'sstone21' stored in the ITIM Schema of the LDAP directory is shown in Figure 7.

Figure 7. LDAP ITIM schema
Figure 7. LDAP ITIM schema

Also, ITIM Person 'Sharon Stone's' existing WPS account with user ID 'sstone' and password 'sstone21' stored in the WPS Schema of the LDAP directory is shown in Figure 8.

Figure 8. LDAP WPS schema
Figure 8. LDAP WPS schema

Subsequent to WPS login (using user ID 'sstone' and password 'sstone21'), navigate to the Landing (menu) screen of the Struts JSR168 Portlet on the 'TivoliSecurityTesting' WPS Page configured previously as shown in Figure 9.

Figure 9. (menu) screen
Figure 9. (menu) screen

Change Password use case

The Change Password functionality (use case) can be described using the following screenshots.

  1. Click the Change Password link on the Landing (menu) screen.
    Figure 10. Change Password screen
    Figure 10. Change Password screen
  2. ITIM Person 'Sharon Stone's' old password ('sstone21') and a new password, for example, 'sstone71'. Then click the Change Password button.
    Figure 11. Change Password confirmation screen
    Figure 11. Change Password confirmation screen

    Clicking on the 'Back' link will return you to the Landing (menu) screen of the Struts JSR168 Portlet.

Change Profile use case

The Change Profile functionality (use case) can be described using the following screenshots.

  1. Click the Change Profile link on the Landing (menu) screen.
    Figure 12. Change Profile Screen
    Figure 12. Change Profile Screen
  2. 2. Change ITIM Person 'Sharon Stone's' profile information as shown in Figure 13. Then click the Change Profile button.
    Figure 13. Change Profile screen - change ITIM Person Profile information
    Figure 13. Change Profile screen - change ITIM Person Profile information
    Figure 14. Change Profile confirmation screen
    Figure 14. Change Profile confirmation screen
  3. Success of the Change Profile can be verified as follows:
    a.

    The screenshot in Figure 15 of the ITIM Schema of the LDAP directory particular to ITIM Person 'Sharon Stone' reveals that her ITIM account is modified based on the profile information entered in Step 2 above.

    Figure 15. LDAP ITIM schema - Change Profile
    Figure 15. LDAP ITIM schema - Change Profileb.

    Similarly, Figure 16 of the WPS Schema of the LDAP directory particular to ITIM Person 'Sharon Stone' reveals that her WPS account is modified based on the profile information entered in Step 2 above.

    Figure 16. LDAP WPS schema - Change Profile
    Figure 16. LDAP WPS schema - Change Profile

    Clicking on the 'Back' link will return you to the Landing (menu) screen of the Struts JSR168 Portlet.


Conclusion

This article attempted to share knowledge around the following objectives:

  1. What ITIM is and how the ITIM API is logically designed.
  2. How a Struts JSR168 Portlet can use the ITIM API to leverage the ITIM self-care (password and other profile information) provisioning functionality from within WPS.

Downloads

DescriptionNameSize
Sample code for this article1StrutsJSR168Portlet_ITIMAPI_v1.0.0.zip6350KB
A related PDF (not of the article)2Configuration_of_the_Solution_Screenshots.pdf1756KB

Notes

  1. StrutsJSR168Portlet_ITIMAPI_v1.0.0.zip archive accompanying this article contains:
    a. Deployable Struts JSR168 portlet archive TivoliWpsStrutsPortlet.war.
    b. TivoliWpsStrutsPortlet-SourceCode directory consisting of source code for the Struts JSR168 portlet.
    c. WAS directory consisting of wsjaas.conf configuration file.
  2. Configuration_of_the_Solution_Screenshots.pdf document contains screenshots applicable to the 'Configuration of the Solution in an Existing ITIM/WPS Environment' Section of the article.

Resources

More downloads

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Tivoli (service management) on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Tivoli (service management), Tivoli
ArticleID=199757
ArticleTitle=Leveraging the IBM Tivoli Identity Manager's (ITIM) self-care provisioning functionality from a Struts JSR168 Portlet using the ITIM API
publish-date=03262007