Using credential vault to provide single sign-on for portlets

This article provides and explains four portlet applications that use different credential vault techniques to maintain credentials.

Sukumar Konduru (konduru@us.ibm.com), Advisory Software Engineer, IBM Dallas, Developer Technical Support Center

Sukumar Konduru is an Advisory Software Engineer at the IBM Dallas, Developer Technical Support Center. He holds M.S in Computer Science from University of Houston. You can reach Sukumar Konduru at konduru@us.ibm.com.



06 November 2002

Introduction

Some portlets that run on WebSphere® Portal server need to submit credentials (for example, a user ID and a password) to back-end remote applications. If the remote applications use the same credentials as those used by WebSphere Portal, then portlets can re-use them. Portlets can use the Java Authentication and Authorization Service (JAAS) API to extract those credentials, and then submit them to the remote applications. However, it is not always possible for a remote application to use the same credentials as those used by WebSphere Portal. Therefore, to enable a single sign-on experience for the user, WebSphere Portal Version 4.1 Enable Offering provides a credential vault mechanism that portlets can use to set and retrieve credentials securely.

This article provides and explains four portlet applications that use different credential vault techniques to maintain credentials. Developers can use these applications as models to write their own portlets. Readers should have a basic understanding of developing and installing portlets, and of customizing pages.


Understanding the credential vault

The credential vault is a repository where credentials are stored. Examples of credentials include certificates, private keys, user IDs, and passwords. WebSphere Portal provides a class called CredentialVaultService which portlets can use to store and retrieve credentials from the vault.

A vault adapter is a plug-in module between the credential vault and CredentialVaultService. WebSphere Portal provides a simple adapter using the portal database as a default vault and another adapter for Tivoli Access Manager. You can extend the VaultAdapter class, in the portal framework, to develop an adapter interface to your own repository. You need to specify any newly created adapters in the vault configuration file, WebSphere\AppServer\lib\app\config\services\VaultService.properties.

A vault segment is a partition of a vault. There are two types of segments: user-managed and administrator-managed. Portal administrators can create administrator-managed segments using the Credential Vault tab on the Security page of the Portal Administration place. This tab is called the Credential Vault portlet. WebSphere Portal provides a user-managed segment in the default vault.;

A vault slot is part of a vault segment; it is represented using CredentialSlotConfig class. Portlets use vault slots to store and retrieve credentials. You can create a vault slot programmatically, in a user-managed segment. An administrator can also create a slot in an administrator-managed segment, using the Credential Vault portlet. The portlet can set and get credentials in slots created either way. The CredentialSlotConfig object contains configuration information about the slot; for example, the slot ID, segment object ID, and other attributes.

There are two types of credentials: active and passive. Passive credentials allow a portlet to extract the credential's secret. Active credentials do not allow a portlet to extract the credential's secret. However, active credentials can submit credentials to back-end applications using standard authentications, such as HTTP form-based authentication or basic authentication. You can explore the package com.ibm.wps.portletservice.credentialvault.credentials from the WebSphere Portal API documentation to understand more about credentials.

The portlets described in the following sections use vault slots that are created programmatically and created by an administrator in the default vault. All the portlets described below use passive credentials.


Sample portlet applications

This article provides code examples for four sample portlet applications. You can install the applications to understand different ways to create vault slots, and to set and get credentials into vault slots.

The credential vault provided by WebSphere Portal defines four types of vault slots:

  • Portlet private slot: Stores user credentials that are not shared among portlets. The Private Slot Portlet application demonstrates the private slot.
  • Shared slot: Stores user credentials that are shared among the user's portlets. The Shared Slot Portlet application demonstrates the shared slot.
  • Administrative slot: Allows each user to store a secret for an administrator-defined resource (for example, Lotus Notes). The Administrative Slot Portlet application demonstrates the administrative slot.
  • System slot: Stores system credentials where the actual secret is shared among all users and portlets. The System Slot Portlet application demonstrates system slot.

Portlets belonging to all of these sample applications, except for System Slot Portlet Application, support both edit and view modes. A user can select edit mode to store credentials into the vault and view mode to see credentials that have been set.

The administrator must create slots for the System Slot Portlet and Administrative Slot Portlet applications. For System Slot Portlet application, in view mode, the portlet displays a shared user ID and password pair.

The Private Slot Portlet and Shared Slot Portlet applications create slots programmatically, when a user first submits credentials using edit mode.

All these sample applications demonstrate how to store passive credentials of type user ID and password.


Private Slot Portlet application

The Private Slot Portlet application contains a single portlet, PrivateSlotSamplePortlet. Since this portlet creates a private slot, only that portlet instance can access credentials from the slot; the user's other portlets cannot access this slot. This application illustrates how to:

  • Initialize the CredentialVaultService
  • Create a private slot and set credentials
  • Access credentials from the private slot

The code for this application is in the attached privateslotsample.war. This WAR file contains PrivateSlotSamplePortlet.java class, in the WEB-INF\classes\samplepkg directory.

The POP3 mail portlet is an example where using a private vault slot is especially appropriate. For example, suppose a user:

  • Customizes a page by adding two instances of the POP3 portlet
  • Connects one instance to a business email account
  • Connects the other to a personal email account

When a portlet creates a private slot, each instance stores its own credentials. Although both instances create private slots using the same resource name, the credential vault internally appends the unique portlet instance id to the resource name. If a developer builds a portlet that connects to a POP3 mail account, the portlet may use private slot to store credentials independently.

Initializing CredentialVaultService

The CredentialVaultService is a portlet service that portlets can use to create vault slots for storing and retrieving credentials. Listing 1 shows how to initialize a service object as the data member vaultService. It is accessed multiple times from member methods.

Listing 1. Initializing the CredentialVaultService object
public void initConcrete(PortletSettings settings) throws UnavailableException { 
  super.initConcrete(settings); 
  try{ 
    vaultService = (CredentialVaultService) getPortletConfig().getContext(). 
                    getService(CredentialVaultService.class); 
  } 
  catch(Exception e){ 
    return; 
  } 
}

Creating private vault slot and setting credentials

Let's assume a user customizes a page by adding an instance of PrivateSlotSamplePortlet. If he then selects the edit mode icon, a form displays prompting him to enter a user ID and password. After the user submits a user ID and password, Portal invokes the actionPerformed method, which is shown in Listing 2. The first time the user submits the form, the PrivateSlotSamplePortlet uses the createSlot method with the following arguments, to create the private vault slot.

  • resourceName: The name of the back-end application.
  • segmentID: The ID of the vault segment in which the slot needs to be created. The segment should be a user-managed segment. The code below obtains the value using:
    vaultService.getDefaultUserVaultSegmentId()
    vaultService.getDefaultUserVaultSegmentId()
  • descriptionMap, keywordMap: Describes the vault slot keyed by locale, and keywords respectively. They are set as empty map objects in the sample code.
  • secretType: A constant defined in CredentialVaultService. Since the vault slot is needed to store the user ID and password, it is set to:
    vaultService.SECRET_TYPE_USERID_STRING_PASSWORD_STRING
    vaultService.SECRET_TYPE_USERID_STRING_PASSWORD_STRING
  • active: Tells whether credentials are active (true) or passive (false). Since the sample portlet needs to retrieve user ID and password, it is set to false.
  • portletPrivate: Tells whether the credential secret is portlet specific (true) or shared among all of a user's portlets (false). It is set to true to allow access only from the portlet instance that creates the slot.

The returned object of createSlot is of type CredentialSlotConfig and is used to get access to the slotID. This slotID is stored in PortletData. It must be persistent so that portlets can access and update credentials. The setCredentialSecretUserPassword method stores the user ID and password into the credential vault using the slotID. Listing 2 shows creating a private vault slot and storing credentials into the slot.

Listing 2. Creating a vault slot and storing credentials
public void actionPerformed(ActionEvent event) throws PortletException { 
  DefaultPortletAction action = (DefaultPortletAction) event.getAction(); 
 
  if( (action == null) || (!action.getName().equals("save") ) ) 
    return; 
 
  PortletRequest portletRequest = event.getRequest(); 
  String userID   = (String) portletRequest.getParameter("userID"); 
  String password   = (String) portletRequest.getParameter("password"); 
 
  // save only if both parameter are set 
  if(userID ==null || password ==null || userID.trim().equals("") 
               || password.trim().equals("")) 
    return; 
  try{ 
    PortletData data = portletRequest.getData(); 
    String slotId = (String) data.getAttribute("PrivateSlotSamplePortletSlotID"); 
 
    if(slotId==null) { // create slot if necessary 
 
      String resourceName = "POP3MailApp"; 
      ObjectID segmentID = vaultService.getDefaultUserVaultSegmentId(); 
      Map descripMap = new Hashtable(); 
      Map keywordMap = new Hashtable(); 
      int secretType = vaultService.SECRET_TYPE_USERID_STRING_PASSWORD_STRING; 
      boolean active = false; 
      boolean portletPrivate = true; 
 
      //create the slot 
      CredentialSlotConfig slot= vaultService.createSlot 
        (resourceName, segmentID,descripMap, 
        keywordMap, secretType, active, portletPrivate, portletRequest); 
      slotId=slot.getSlotId(); 
      data.setAttribute("PrivateSlotSamplePortletSlotID", slot.getSlotId()); 
      data.store(); 
    } 
    // store credentials in vault 
    vaultService.setCredentialSecretUserPassword(slotId, userID, 
          password.toCharArray(),portletRequest); 
  } 
  catch(Exception e){ 
    e.printStackTrace(System.out); 
  } 
}

Accessing credentials

In the previous section, you saw how to create a vault slot and store credentials into it. This section illustrates how to extract the stored credentials from the vault slot.

The PrivateSlotSamplePortlet retrieves slotID from the PortletData object, using the getAttribute method. The getCredential method expects slotID as an argument. The getCredential method first makes sure that a slotID exists. If the slot ID is not present, the getCredential method exits. Since the stored credentials are passive and they are, specifically, the user ID and password, the argument for type is set to UserPasswordPassive.

The getCredential method returns an object of type UserPasswordPassiveCredential and contains the user ID and password. Both doView and doEdit methods call getCredential method to display the stored user ID and password in the portlet window or to populate the values into text fields of the edit form, respectively.

Listing 3. Extracting the credentials from the private slot
private void getCredential(PortletRequest portletRequest,StringBuffer user ID, 
          StringBuffer password) throws PortletServiceException { 
  try{ 
    String slotId = (String) portletRequest.getData().getAttribute 
                    ("PrivateSlotSamplePortletSlotID"); 
 
    if(slotId==null) 
      return ; 
 
    UserPasswordPassiveCredential credential =(UserPasswordPassiveCredential) 
        vaultService.getCredential 
        (slotId, "UserPasswordPassive", new HashMap(), portletRequest); 
    userid.append(credential.getUserId() ); 
    password.append( String.valueOf(credential.getPassword() ) ); 
  } 
  catch(com.ibm.wps.portletservice.credentialvault.
        CredentialSecretNotSetException e){ 
    return ; 
  } 
  }

Running the Private Slot Portlet application

Install the attached Private Slot Portlet application into WebSphere Portal Version 4.1.2. Customize a page by adding two instances of PrivateSlotSamplePortlet on it.

For one instance of the portlet, choose edit mode and submit a user ID and password. The portlet creates a vault slot and stores the user ID and password into the credential vault. Only this portlet instance extracts the user ID and password from the credential vault and displays them.

Follow similar steps using the other portlet instance to submit a user ID and password. Each portlet instance displays its unique user ID and password (or its own credentials). Figure 1 shows a customized page with two instances of PrivateSlotSamplePortlet,each displaying its own user ID and password.

Figure 1. Two instances of PrivateSlotSamplePortlet that have different credentials
Two instances of PrivateSlotSamplePortlet that have different credentials

Shared Slot Portlet application

The Shared Slot Portlet application contains two portlets, SharedSlotSamplePortlet1 and SharedSlotSamplePortlet2. Except for the names of the classes, the code for each is exactly the same.

When the user first submits his user ID and password from either of the portlets, that portlet creates a shared vault slot and stores the users credentials in it. The shared slot allows other portlets to retrieve and display the credentials. This portlet application demonstrates how to create a shared vault slot, access the shared slot, and set and get credentials. You can examine the code for this application by downloading and opening the sharedslotsample.war. The WAR file contains SharedSlotSamplePortlet1.java and SharedSlotSamplePortlet2.java classes, located in WEB-INF\classes\samplepkg directory.

This ability to create shared slots is useful when a company uses the same intranet user ID and password to authenticate a user to access multiple back-end applications. If there are multiple portlets that connect to the back-end applications, the user does not need to specify his user ID and password for each portlet. One portlet can set user credentials in a shared slot and the other portlets can access it to retrieve the user credentials.

Creating a shared vault slot

Creating a shared vault slot is similar to creating a private slot. However, you set the portletPrivate flag, passed as an argument for createSlot method, to false to share the vault slot among all portlet instances associated with a single user. The portlet can get the resourceName argument for the createSlot method is from portlet.xml.

Accessing shared slot

If the user sets credentials in edit mode for either SharedSlotSamplePortlet1 or SharedSlotSamplePortlet2, then the portlet displays credentials, when in view mode. If the user sets credentials, the doView method of each portlet calls getCredentialSlotConfig method to get an object of type CredentialSlotConfig. The getAccessibleSlots method, which is called from the getCredentialSlotConfig method, returns an iterator containing objects of type CredentialSlotConfig. This iterator can be explored to determine whether it contains CredentialSlotConfig object related to the same resource name which is passed while creating the slot. Because WebSphere Portal appends the object ID of the user to the resource name, the extracted resource name should always be compared using the String class startswith method to determine whether or not it matches the resource. Listing 4 demonstrates finding the slot.

Listing 4. Finding the slot that corresponds to a resource name
private CredentialSlotConfig getCredentialSlotConfig
                              (PortletRequest  portletRequest) { 
  java.util.Iterator it = null; 
  try{ // creates list of accessible slots 
    it= vaultService.getAccessibleSlots(portletRequest); 
  }catch(PortletException pe) 
  { 
    return null; 
  } 
  CredentialSlotConfig config =null ; 
  String curResName = null; 
 
  while(it.hasNext() ) 
  { 
    config =(CredentialSlotConfig )it.next() ; 
    curResName = config.getResourceName(); 
 
    //searches for shared resource name 
    if (curResName.startsWith(resourceName ) ) 
       return config; 
    } 
  return null; 
}

Setting and getting credentials using a shared slot

Portlets store and retrieve credentials, using a shared slot, the same way they do using a private slot. They extract the slotID from the CredentialSlotConfig object, which they access using the getCredentialSlotConfig method.

Install and customize Shared Slot Portlet application

  1. Install the Shared Slot Portlet application and customize a page by adding one instance each of SharedSlotSamplePortlet1 and SharedSlotSamplePortlet2 to it.
  2. For one of the portlets, choose edit mode.
  3. Submit a user ID and password.
    The selected portlet creates a shared vault slot and stores the user ID and password credentials into the credential vault. The other portlet extracts the credentials from the vault, using the shared vault slot, and displays the same user ID and password.
Figure 2. Instances of SharedSlotSamplePortlet1 and SharedSlotSamplePortlet2 that have same credentials
Instances of SharedSlotSamplePortlet1 and SharedSlotSamplePortlet2 that have same credentials

Administrative Slot Portlet application

The Administrative Slot Portlet application includes one portlet, AdminSlotSamplePortlet. Unlike the Private Slot and Shared Slot Portlet applications, in this sample application, the vault slot is not created in the portlet code. Instead, the portlet expects that a vault slot has been created using the Credential Vault portlet. It looks for the slot name as a configuration parameter for the concrete portlet in portlet.xml.

When the Administrator creates the vault slot, he makes sure the Vault slot is shared check box is not checked, to indicate that users do not share the slot. Although the slot is not shared among portlet instances associated with different users, it is shared across all instances of a single user's portlets.

The sample portlet in this application uses APIs for setting and getting credentials using CredentialVaultService. This portlet application demonstrates how to create an administrative slot, configure a slot name, and set and get credentials. The code for this application is in adminslotsample.war, which contains AdminSlotSamplePortlet.java class, located in WEB-INF\classes\samplepkg directory.

The design pattern for the Administrative Slot Portlet application is similar to that of the Shared Slot Portlet application. However, the Administrative Slot Portlet application shows how an administrator can create and delete slots using the Credential Vault portlet.

Creating an administrative slot

  1. Login to WebSphere Portal as portal administrator.
  2. Select Portal Administration->Security->Credential Vault Portlet.
  3. Click on Add a Vault Slot.
  4. Enter following values:
    Setting Value
    VaultDefault
    NameAdminSlot1
    Vault segmentDefaultAdminSegment
    Vault slot is sharedUncheck
    Vault resource associated with vault slotSelect new and enter "Lotus"
  5. Click OK to create an administrative slot.
Figure 3. Creating an administrative slot
Creating an administrative slot

Configuring slot name and setting and getting credentials

The administrator sets the slot name as a configuration parameter in portlet.xml, using the following code. The slot name is stored in the portlet class as a vaultSlotName data member.

<context-param> 
  <param-name>VaultSlotName</param-name> 
  <param-value>AdminSlot1</param-value> 
</context-param>

Portlets can set and retrieve credentials using CredentialAccessService class as described in previous sections. The following code fragment sets credentials in portlet code using the setCredentialSecretUserPassword method.

vaultService.setCredentialSecretUserPassword(VaultSlotName, 
   userID, password.toCharArray(), portletRequest);

The following code fragment gets credentials in portlet code using the getCredential method.

UserPasswordPassiveCredential credential = (UserPasswordPassiveCredential) 
   vaultService.getCredential(VaultSlotName,"UserPasswordPassive", new HashMap(), 
   portletRequest);

Both of these methods use vaultSlotName as the slotID argument.

Installing portlet and customizing page

  1. Install the attached Administrative Slot Portlet Application.
  2. Customize a page by adding two instances of AdministrativeSlotSamplePortlet on it.
  3. For one of the portlets, choose edit mode and submit a user ID and password.
    That portlet stores credentials into credential vault using administrator created slot. The other portlet by extracts the user ID and password from the credential vault and displays them.

This portlet is similar to Shared Slot sample portlet except that the slot is created by an administrator.

Figure 4. Two instances of AdminSlotSamplePortlet that have same credentials
Two instances of AdminSlotSamplePortlet that have same credentials

System Slot Portlet application

System Slot Portlet application includes one portlet, SystemSlotSamplePortlet. The portlet code does not create the vault slot; instead, it expects that a vault slot has been created using the Credential Vault portlet. The slot name is set as a configuration parameter for concrete portlet in portlet.xml.

When the administrator creates the vault slot, he checks Vault slot is shared and specifies a shared user ID and password. Selecting this setting indicates the slot is shared among all users.

This portlet application demonstrates how to create a system slot, configure a slot name, and set and get credentials. You can examine the code for this portlet application by downloading and opening the systemslotsample.war. This WAR file contains SystemSlotSamplePortlet.java class, located in WEB-INF\classes\samplepkg directory.

The System Slot Portlet application design pattern is particularly appropriate if a portlet needs to connect to a mainframe using the mainframe administrator userID. Portlets associated with all users can submit shared credentials to back-end applications by retrieving them from the system slot.

Creating a system slot

  1. Login as portal administrator.
  2. Select Portal Administration->Security->Credential Vault Portlet.
  3. Click on Add a Vault Slot.
  4. Enter following values:
    Setting Value
    VaultDefault
    NameSystemSlot1
    Vault slot is sharedcheck
    Vault SegmentDefaultAdminSegment
    Vault resource associated with vault slotSelect new and enter MainFrameDB1
    Shared User IDdbadmin
    Shared Passwordxyzabc
    Confirm Passwordxyzabc
  5. Click OK to create a system slot.
Figure 5. Creating a system slot
Creating a system slot

Configuring slot name and setting and getting credentials

The portlet developer sets the slot name as a configuration parameter value using the following code in portlet.xml. WebSphere Portal stores the slot name in the portlet object as a vaultSlotName data member.

<context-param> 
  <param-name>VaultSlotName</param-name> 
 	<param-value>SystemSlot1</param-value> 
</context-param>

Portlets can set and retrieve credentials using CredentialAccessService class as described in previous sections.

Installing portlet and customizing page

Install attached System Slot Portlet Application and customize a page by placing an instance of SystemSlotSamplePortlet on it. The portlet window displays the shared user ID and password that the administrator entered while creating the slot.

Figure 6: An instance of SystemSlotSamplePortlet displaying stored credentials


Conclusion

This article demonstrates various ways of creating vault slots, and storing and retrieving credentials using the default vault. You can use the code snippets in the sample portlet applications as examples to embed in existing portlets. Using these techniques, you can enable a user single sign-on to connect to back-end applications that need authentication. WebSphere Portal developers can also implement vault adapters that use their own repository as a vault instead of using default vault.


Downloads

DescriptionNameSize
Code sample in war formatprivateslotsample.war  ( HTTP | FTP )11 KB
Code sample in war formatsharedslotsample.war  ( HTTP | FTP )21 KB
Code sample in war formatadminslotsample.war  ( HTTP | FTP )10 KB
Code sample in war formatsystemslotsample.war  ( HTTP | FTP )9KB

Resources

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 WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=87067
ArticleTitle=Using credential vault to provide single sign-on for portlets
publish-date=11062002