Part 5 and Part 6 of the employee workplace series describe how to create Document Management portlets to access DB2 Content Manger. However, they don't discuss the authentication in detail. This article will briefly discuss the authentication approach implemented in the Document Management portlets, and show you how to use another authentication approach to implement the single sign-on feature.
The following products are used in this article:
- Lotus Workplace for Multiplatforms Version 2.01
- IBM DB2 Content Manager for Multiplatforms Version 8.2
- IBM DB2 Information Integrator for Content Version 8.2
- IBM WebSphere Application Server Version 5.1
- IBM WebSphere Studio Application Developer Version 5.1.2
- IBM Portal Toolkit Version 5.0.2
- IBM DB2 Universal Database Enterprise Version 8.1
The main difference between the system environment in this article and the environment used in the employee workplace series is that we use Lotus Workplace 2.01 instead of WebSphere Portal Server 5.0. The Lotus Workplace server 2.0.1 is running on top of WebSphere Portal Server 5.0 as an application server. It provides an integrated enterprise working environment, which allows users to manage mail, send instant messages, and run portlet applications. No code changes were necessary to migrate the Document Management portlets to Lotus Workplace.
All user information is stored in a single LDAP user registry, so that the user information in Lotus Workplace and DB2 Content Manager is synchronized. This is necessary for the authentication approach used in this article.
The DB2 Content Manager Server is integrated with portlets as a back-end server, so when you use a portlet to access the DB2 Content Manager, you need to authenticate at the server. One of the authentication approaches is to use DB2 Content Manager APIs with the user name and password. The portlet needs either to prompt for the username and password, or to use the username and password stored in the portlet when connecting to the DB2 Content Manager Server.
The Document Management portlets store the credentials -- for example, the username and password -- in the Credential Vaults of the portlets. The credentials are maintained by each user within portlets, which must be synchronized with the user registry. This hides the login challenge of DB2 Content Manager from the user.
However, this approach has a few disadvantages. First, it needs to provide a user interface for users to maintain their DB2 Content Manager credentials. Second, it is not convenient for users to manually synchronize the credentials with the user registry while the portlets and the DB2 Content Manager server are sharing the same user registry server. Third, it exposes the credentials as the username and password, which may introduce some security vulnerabilities.
To avoid these shortcomings, you can use the Light-weight Third Party Authentication (LTPA) token approach discussed below to provide the single sign-on capability.
You can use the LTPA token to provide the single sign-on capability among servers. When the WebSphere Application server, which hosts the Lotus Workplace server, is configured to use the LTPA token for single sign-on, the LTPA token (which is a cookie) contains the authenticated user credential.
Besides the Java API that uses the username and password to connect to the DB2 Content Manager server, The DB2 Information Integrator for Content Java API also provides non-visual beans that can use an LTPA token as an authentication credential to connect to the DB2 Content Manager server. It does not require users to maintain their credentials manually, and also does not expose the credentials as usernames and passwords. However, it requires both Lotus Workplace and DB2 Content Manager to accept LTPA tokens for single sign-on.
Configuring Lotus Workplace and DB2 Content Manager
As mentioned above, the Lotus Workplace server is running on top of the WebSphere Portal server, while the WebSphere Portal server is running within the WebSphere Application server. To configure single sign-on for the Lotus Workplace server, enable single sign-on for the WebSphere Application server. For detailed instructions, refer to the section "Configuring Lotus Workplace products for seamless authentication" in Lotus Workplace Information center (see Resources).
To integrate with the Lotus Workplace using the single sign-on feature, perform the following configuration in the DB2 Content Manager server, using a Content Manager System Administration Client:
- Enable the single sign-on feature in the Content Manager server.
- Create a new privilege set that contains AllowConnectToLogon and AllowTrustedLogon privileges and any other necessary privileges (for example, ClientPrint).
Tip: to create a new privilege set based on an existing one, you can right-click the existing privilege set and select Copy. A new window will open, where you can create a new privilege set by adding new privileges while keeping the existing ones. - Assign the newly created privilege set to any user accounts that will need to log in to the Content Manager server with single sign-on.
Use eClient to verify if the single sign-on feature is working. For detailed instructions, refer to the section "17.4 Configuring Content Manager V8.2 for SSO" in the eClient101 Customization and Integration redbook (see Resources).
Developing single sign-on portlets using LTPA tokens
This section explains how to develop single sign-on portlets for DB2 Content Manager using LTPA tokens. The first step is to create a new single sign-on portlet step by step, rather than modifying the Document Management portlets directly. Next you'll seek out where to change the code in the portlets so that they have the single sign-on feature by using LTPA tokens.
Creating a new single sign-on portlet
First, follow the steps below to create the skeleton of the new portlet:
- In WebSphere Studio Application Developer, select File > New > Project. Click Next.
- Select Portlet Development in the left panel, and then select Portlet Project in the right panel. Click Next.
- Type CMSSO in the Project name field, select Basic portlet as the type of the new portlet, and select the Configure advanced options checkbox. Click Next.
- Type CMSSOEAR in the EAR project field, keep CMSSO as the Content root, and select J2EE level 1.3\WebSphere Portal 5.0. Click Finish.
- In the Portlet Perspective view, select Window > Preference.
- Select Java > Classpath Variable in the left panel. Click New in the right panel.
- Type CMBROOT in the Name field. Type the installed path of Content Manager in the Path field (for example:
X:\Program Files\IBM\CM82). Click OK. - Type CMBHOME in the Name field. Type the directory name of common files of Content Manager in the Path field (for example:
X:\Program Files\IBM\CMgmt). Click OK. - In the Portlet Perspective view, right-click the CMSSO project and select Properties.
- Click Add Variable. Select CMROOT and click Extend. Select lib\cmb81.jar and click OK.
- Click Add Variable. Select CMROOT and click Extend. Select lib\cmbsdk81.jar and click OK.
- Click Add Variable. Select CMHOME and click OK.
In the steps above, you created a new sample portlet and added some of Content Manager's Java libraries (cmb81.jar and cmbsdk81.jar) to the project classpath. Now you can Import the sample Java programs TConnect.java and TListEntities.java (which came bundled with Content Manager), to test the Content Manager authentication for the portlet. TConnect.java is a utility class for connecting to the Content Manager server. TListEntities.java displays details on types of entities defined on the Content Manager server. Follow the steps below to integrate the two Java files with the portlet.
- In the Portlet Perspective view, select the CMSSO project > Java Resources > cmsso. Right-click cmsso and select Import. Locate the files TConnect.java and TListEntities.java, and import them.
- Add package cmsso at the beginning of the two files above and compile.
- In the CMSSOPortlet.java file, modify the actionPerformed() function as follows.
if (FORM_ACTION.equals(actionString)) { // Set form text in the session bean sessionBean.setFormText(request.getParameter(TEXT)); // Replace the parameters with the proper values String [] args ={"ICM","ICMNLSDB","icmadmin","password"}; try { TListEntities.main(args); } catch (Exception e) { e.printStackTrace(System.out); } } System.out.println("<------Submit button pressed--->");
- Export the project as WAR files, and deploy it to the Lotus Workplace server.
- Add the Content Manger common directory to the Portal classpath. From the WebSphere Administrative Console select Environment > Shared Libraries, and click WPSLIB. Add the directory where common files are shared by Content Manager and Information Integrator for Content (for example:
D:\IBM\Cmgmt) to the CLASSPATH and then click OK. - Restart the server, and log in to Lotus Workplace. Load the page that has the portlet and click the Submit button to see if the log file prints out the types of entities defined on the Content Manager server.
If the portlet is working properly, you can start to modify the code to add LTPA token authentication. The DB2 Information Integrator for Content Java API provides a non-visual bean, CMBConnection, that you can use to connect to the DB2 Content Manager Server using an LTPA token as the authentication credential.
The method connectWithCredential() of CMBConnection accepts three parameters: server name, credential object, and connect string. To enable the use of a LTPA token as the credential when connecting to the Content Manager server, add the following code to connect to the Content Manager server to TConnect.java:
/**
* Connects to a given server using LTPA token.
* @param connection an instance of CMBConnection bean
* @param dstype the datastore type.
* @param server the server name. A connection string can
* also be specified following the name, in parenthesis
* @param ltpaToken the ltpaToken.
*/
public static void connect(CMBConnection connection, String dstype,
String server, String ltpaToken)
throws Exception {
// If the server name is followed by a parenthesized string,
// use that string for the connect string.
if (server.indexOf("(") > 0) {
String connectString = server.substring(server.indexOf("(")+1);
server = server.substring(0, server.indexOf("("));
if (connectString.endsWith(")")) {
connectString = connectString.substring(0,
connectString.length() - 1);
}
connection.setConnectString(connectString);
}
// Set properties on connection bean
connection.setDsType(dstype);
// Use the connect method to connect. This will
// create the correct type of DKDatastore object (see Java API)
// and call its connect method.
System.out.println("Connecting to server");
connection.connectWithCredential(server, ltpaToken, "");
System.out.println("OK, Connected");
// Enable display names support. This will cause
// CMBSchemaManagement, CMBEntity, CMBAttribute, CMBItem to use
// display names when working with CMv8 (default is to use
// non-display names).
connection.setDisplayNamesEnabled(true);
}
|
To use the new connect() method in TConnect.java, you'll need to modify the main() function of TListEntities.java as well. The following is the code of the new main() method:
public static void main(String[] args) throws Exception {
if (args.length < 3) {
System.out.println(
"Displays details on types of entities defined on the server. \n"
+ "Syntax: \n"
+ " java TListEntities <dstype> <server> <ltpaToken> [<entity>] \n"
+ "where: \n"
+ " <dstype> is the type of server (Fed, ICM, DL, OD, DB2) \n"
+ " <server> is the name of the server or database. This can be \n"
+ " followed by a connect string in parenthesis. \n"
+ " <ltpaToken> is the ltpaToken \n"
+ " <entity> optional, the name of a particular entity. Detailed \n"
+ " information will be displayed about the entity. \n"
+ "Examples: \n"
+ " java TListEntities ICM icmnlsdb ltpaToken \n"
+ " java TListEntities ICM icmnlsdb ltpaToken 'Document (for Document data model)' \n"
+ " java TListEntities DL libsrvrn ltpaToken \n"
+ " java TListEntities Fed cmbdb ltpaToken \n"
+ " java TListEntities DB2 sample ltpaToken emp_photo \n"
+ " java TListEntities OD odserver ltpaToekn \n"
+ "where single quotes are used around entity and attribute names that contain spaces");
System.exit(0);
}
String dstype = args[0];
String server = args[1];
String ltpaToken = args[2];
String entity = null;
int nextArg = 4;
if (nextArg < args.length && args[nextArg] != null) {
if (args[nextArg].startsWith("'"))
{
String arg = args[nextArg];
while (nextArg <args.length && !arg.endsWith("'"))
{
nextArg++;
arg += " "+args[nextArg];
}
entity = arg.substring(1,arg.length()-1);
}
else
entity = args[nextArg];
}
CMBConnection connection = new CMBConnection();
CMBSchemaManagement schemaManagement = connection.getSchemaManagement();
schemaManagement.setChildComponentsAsAttributes(childComponentsAsAttributes);
TConnect.connect(connection, dstype, server, ltpaToken);
if (entity == null) {
listEntities(schemaManagement);
} else {
printEntityDetails(schemaManagement.getEntity(entity), 1, true);
}
TConnect.disconnect(connection);
}
|
To invoke the new main() method of TListEntities.java, modify the actionPerformed() method of CMSSOPortlet.java. First, get the LTPA token. Then pass it to the main() function. The LTPA token, which is a cookie, and can be retrieved from PortletRequest Java object. The following is the code to retrieve the LTPA token and invoke TListEntities.main():
...
Cookie[] cookies = request.getCookies();
String LtpaToken = null;
if (cookies != null && cookies.length > 0) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equalsIgnoreCase("LtpaToken")) {
LtpaToken = cookies[i].getValue();
}
}
}
String [] args ={"ICM","ICMNLSDB",""};
args[2] = LtpaToken;
try {
TListEntities.main(args);
} catch (Exception e) {
e.printStackTrace(System.out);
}
System.out.println("<------ Submit button pressed. --->");
...
|
Now you have finished the single sign-on portlet. You can build the project, export it as a WAR file, and deploy it to the Lotus Workplace server.
Enhance the Document Management portlets with single sign-on
After you test the new single sign-on portlet created above, you may start to enhance the Document Management portlets developed in Part 5 and Part 6 of the series.
Adding the single sign-on feature is a two-step process. First, you need to add a function for connecting to the Content Manager server using LTPA token. Second, you need to change the code in the portlets where the username and password are retrieved from the credential vault and used to connect to the Content Manager server.
Like the TConnect.java sample, the Document Management portlets have a utility class that has all the connect and disconnect functions. This class is ICMConnectDisconnect. You need to import TConnect.java to the com.ibm.bsd.util package, and add the following code to the ICMConnectDisconnect.java file:
public static DKDatastoreICM connectWithCredential(String
userName, String ltpaToken)
throws DKException, CMBException, Exception {
// retrieve connection parameters from property file
PropertyResourceBundle bundle =
(PropertyResourceBundle) PropertyResourceBundle.getBundle(
BSDConstants.PROPERTY_FILE_NAME);
String database =
bundle.getString(BSDConstants.PROPERTY_DATABASE_NAME);
CMBConnection connBean = new CMBConnection();
// you need to set userid for some CM operations to work
connBean.setUserid(userName);
System.out.println(
"Connecting to datastore (Database '"
+ database
+ "', LtpaToken '"
+ ltpaToken
+ "'");
//connBean.connect();
TConnect.connect(connBean, "ICM", database, ltpaToken);
/*
connBean.setDsType("ICM");
connBean.connectWithCredential("database", ltpaToken, "");
*/
System.out.println("OK, connected");
DKDatastoreICM dsICM =
(com.ibm.mm.sdk.server.DKDatastoreICM)connBean.getDatastore();
System.out.println(
"Connected to datastore (Database '"
+ dsICM.datastoreName()
+ "', LtpaToken '"
+ ltpaToken
+ "').");
return (dsICM);
}
public static String getLtpaToken(PortletRequest request) {
Cookie[] cookies = request.getCookies();
String ltpaToken = null;
if (cookies != null && cookies.length > 0) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equalsIgnoreCase("LtpaToken")) {
ltpaToken = cookies[i].getValue();
}
}
}
return ltpaToken;
}
|
To locate the code that needs to be modified, you can search for getPassword4CMFromCredential and replace the related code with the following:
... //get the portal user id from the portal request object String userId = request.getUser().getUserID() ; //extract the password of the portal user from the portal credentials //String password = //PortletCredential4ICMUtil.getPassword4CMFromCredential(request, //PortletCredential4ICMUtil.getVault(getPortletConfig().getContext()), //userId); String password = ""; //connect using the LTPA token String ltpaToken = ICMConnectDisconnect.getLtpaToken(request); DKDatastoreICM store = ICMConnectDisconnect.connectWithCredential(userId, ltpaToken); // DKDatastoreICM store = // ICMConnectDisconnect.connect(userId,password) ; sessionBean.setDataStore(store) ; ... |
Now you should be able to use the Document Management portlets without maintaining the username and password.
The seamless integration between the Content Manager server and portlets is an important feature to the customer. This article discussed different approaches to integrate those two products with the single sign-on feature and provided the step-by-step instructions on how to configure and develop a single sign-on portlet using LTPA token. It also offered guidance on modifying the Document Management portlets to use the LTPA token approach.
- Participate in the discussion forum.
- "Managing content in an employee workplace: Bring order to chaos in today's overwhelming paperless business environment" (developerWorks, May 2004)
- eClient 101 Customization and Integration (IBM Redbook; 2003)
- Document Management Using WebSphere Portal V5.0.2 and DB2 Content Manager V8.2 (IBM Redbook; 2004)
- Lotus workplace 2.0.1 Information Center
Comments (Undergoing maintenance)






