DB2 Content Manager 8.2 的单点登录 portlet的配置

简介

雇员工作空间系列 的第 5 部分和第 6 部分将描述如何创建 Document Management portlet 来访问 DB2 Content Manger。然而,这两部分并没有详细讨论身份验证。本文将简要地讨论 Document Management portlet 中所实现的身份验证方法,并展示如何使用另一种身份验证方法来实现单点登录(single sign-on)功能。

系统环境

文中使用了下列产品:

  • 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

本文中的系统环境与雇员工作空间系列中使用的环境之间的主要不同是:我们使用的是 Lotus Workplace 2.01,而非 WebSphere Portal Server 5.0。Lotus Workplace 服务器 2.0.1 是运行在 WebSphere Portal Server 5.0 之上的应用服务器。它提供了一个集成的企业工作环境,该环境允许用户管理邮件、发送即时消息和运行 portlet 应用程序。将 Document Management portlet 迁移到 Lotus Workplace 不需要修改任何代码。

所有的用户信息都存储在一个 LDAP 用户注册表中,以使 Lotus Workplace 和 DB2 Content Manager 中的用户信息保持同步。对于本文中所使用的身份验证方法来说,这是必需的。

凭证保险库

DB2 Content Manager Server 是作为后端服务器与 portlet 集成的,因此当您使用 portlet 访问 DB2 Content Manager 时,需要在服务器上进行身份验证。进行身份验证的方法之一就是通过使用用户名和密码来使用 DB2 Content Manager API。在连接 DB2 Content Manager Server 时,portlet 需要提示输入用户名和密码,或提示使用 portlet 中存储的用户名和密码。

Document Management portlet 在 portlet 的凭证保险库(Credential Vault)中存储凭证(credential)—— 如用户名和密码。凭证是由 portlet 中的每位用户维护的,必须与用户注册表同步。这就向用户隐藏了 DB2 Content Manager 的一些与登录有关的复杂问题。

然而,该方法也有一些缺点。首先,它需要为用户提供用户接口,以维护其 DB2 Content Manager 凭证。其次,在 portlet 和 DB2 Content Manager 服务器共享同一用户注册表服务器时,让用户手工控制凭证与用户注册表之间的同步也不是很方便。最后,它将凭证暴露为用户名和密码,这可能引入一些安全缺陷。

为了避免这些缺陷,您可以使用下面将要讨论的轻量级第三方认证(Light-weight Third Party Authentication,LTPA)令牌方法来提供单点登录功能。

LTPA 令牌

可以使用 LTPA 令牌在服务器之间提供单点登录功能。在将 Lotus Workplace 服务器所在的 WebSphere Application 服务器配置为使用 LTPA 令牌进行单点登录时,LTPA 令牌(是一个 cookie)将包含已验证用户的凭证。

除了使用用户名和密码连接 DB2 Content Manager 服务器的 Java API 之外,DB2 Information Integrator for Content Java API 还提供了非可视(non-visual)的 bean,可以使用 LTPA 令牌作为身份验证的凭证来连接 DB2 Content Manager 服务器。非可视的 bean 不需要用户手工维护其凭证,也不需要将凭证暴露为用户名和密码。但它需要 Lotus Workplace 和 DB2 Content Manager 都接受 LTPA 令牌,以便进行单点登录。

配置 Lotus Workplace 和 DB2 Content Manager

Lotus Workplace 2.0.1

正如上面所提到的,Lotus Workplace 服务器是运行在 WebSphere Portal 服务器之上,而 WebSphere Portal 服务器是运行在 WebSphere Application 服务器上。为了给 Lotus Workplace 服务器配置单点登录,需要启用 WebSphere Application 服务器的单点登录。关于详细的指令,请参阅 Lotus Workplace Information Center 中的小节“Configuring Lotus Workplace products for seamless authentication”(请参阅 参考资料)。

DB2 Content Manager 8.2

为了与使用单点登录功能的 Lotus Workplace 进行集成,需要使用 Content Manager System Administration Client 在 DB2 Content Manager 服务器中执行下列配置:

  • 启用 Content Manager 服务器中的单点登录功能。
  • 创建新的权限集,其中包含 AllowConnectToLogonAllowTrustedLogon 权限,以及其他任何必要权限(例如,ClientPrint)。
    提示:为了基于现有的权限集创建一个新的权限集,可以右击现有权限集,然后选择 Copy。这将打开一个新窗口,您可以在该窗口中通过添加新权限并同时保留现有权限来创建一个新的权限集。
  • 将新创建的权限集分配给需要通过单点登录功能登录到 Content Manager 服务器的用户帐号。

使用 eClient 来验证单点登录功能是否起作用。关于详细的指令,请参阅 eClient101 Customization and Integration 红皮书中的小节“17.4 Configuring Content Manager V8.2 for SSO”(请参阅 参考资料)。

开发使用 LTPA 令牌的单点登录 portlet

这一节将阐述如何为 DB2 Content Manager 开发使用 LTPA 令牌的单点登录 portlet。第一步是一步步地创建一个新的单点登录 portlet,而不是直接修改 Document Management portlet。接着,要找出更改 portlet 中的哪些地方的代码,这样,通过使用 LTPA 令牌,这些 portlet 将具有单点登录功能。

创建新的单点登录 portlet

首先,按照下列步骤创建新 portlet 的骨架(skeleton):

  1. 在 WebSphere Studio Application Developer 中,选择 File > New > Project。然后单击 Next
  2. 选择左边面板中的 Portlet Development,然后选择右边面板中的 Portlet Project。最后单击 Next
  3. Project name 字段中输入 CMSSO,然后选择 Basic portlet 作为新 portlet 的类型,并选中 Configure advanced options 复选框。最后单击 Next
  4. 在 EAR project 字段中输入 CMSSOEAR,为 CMSSO 选择 Content root,并选择 J2EE level 1.3\WebSphere Portal 5.0。然后单击 Finish
  5. 在 Portlet Perspective 视图中,选择 Window > Preference
  6. 在左边面板中选择 Java > Classpath Variable。然后单击右边面板中的 New
  7. 在 Name 字段中输入 CMBROOT。在 Path 字段中输入 Content Manager 的安装路径(例如:X:\Program Files\IBM\CM82)。然后单击 OK
  8. 在 Name 字段中输入 CMBHOME。在 Path 字段中输入 Content Manager 的公共文件(common files)的目录名(例如:X:\Program Files\IBM\CMgmt)。然后单击 OK
  9. 在 Portlet Perspective 视图中,右击 CMSSO 项目并选择 Properties
  10. 单击 Add Variable。选择 CMROOT 并单击 Extend。然后选择 lib\cmb81.jar 并单击 OK
  11. 单击 Add Variable。选择 CMROOT 并单击 Extend。然后选择 lib\cmbsdk81.jar 并单击 OK
  12. 单击 Add Variable。然后选择 CMHOME 并单击 OK

在以上步骤中,您创建了新的示例 portlet,并向项目类路径(classpath)添加了一些 Content Manager 的 Java 库(cmb81.jar 和 cmbsdk81.jar)。现在,就可以导入示例 Java 程序 TConnect.java 和 TListEntities.java(与 Content Manager 捆绑在一起),来测试该 portlet 的 Content Manager 身份验证了。TConnect.java 是用来连接 Content Manager 服务器的实用程序类。TListEntities.java 显示 Content Manager 服务器上所定义实体类型的细节。请按照下列步骤将这两个 Java 文件与 portlet 进行集成。

  1. 在 Portlet Perspective 视图中,选择 CMSSO project > Java Resources > cmsso。然后右击 cmsso 并选择 Import。最后找出文件 TConnect.javaTListEntities.java,并导入它们。
  2. 在上面的两个文件开头的地方添加 package cmsso,并对它们进行编译。
  3. CMSSOPortlet.java 文件中,请按照下列内容修改 actionPerformed() 函数。
    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("

  4. 将项目导出为 WAR 文件,并将它部署到 Lotus Workplace 服务器上。
  5. 将 Content Manger 公共目录添加到 Portal 类路径中。从 WebSphere Administrative Console 中选择 Environment > Shared Libraries,并单击 WPSLIB。然后向 CLASSPATH 添加 Content Manager 和 Information Integrator for Content 共享的公共文件(common files)所在的目录(例如:D:\IBM\Cmgmt),最后单击 OK
  6. 重启服务器,并登录至 Lotus Workplace。加载包含 portlet 的页面,并单击 Submit 按钮,查看日志文件是否输出了 Content Manager 服务器上定义的实体类型。

如果该 portlet 正常工作,那么可以开始修改代码来添加 LTPA 令牌验证了。DB2 Information Integrator for Content Java API 提供了非可视的 bean,即 CMBConnection,您可以用它来连接使用 LTPA 令牌作为验证凭证的 DB2 Content Manager Server。

CMBConnection 的方法 connectWithCredential() 接受三个参数:服务器名(server name)、凭证对象(credential object)和连接字符串(connect string)。为了在连接 Content Manager 服务器时启用 LTPA 令牌作为凭证,需要添加下列代码,将 Content Manager 服务器连接到 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);
  }

为了使用 TConnect.java 中的新 connect() 方法,还需要修改 TListEntities.java 的 main() 函数。下面是新的 main() 方法的代码:

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  [] \n"
         + "where: \n"
         + "   is the type of server (Fed, ICM, DL, OD, DB2) \n"
          + "   is the name of the server or database.  This can be \n"
          + "           followed by a connect string in parenthesis. \n"
          + "   is the ltpaToken \n"
          + "   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 

为了调用 TListEntities.java 的新 main() 方法,需要修改 CMSSOPortlet.java 的 actionPerformed() 方法。首先,获取 LTPA 令牌。然后将它传递给 main() 函数。LTPA 令牌是一个 cookie,可以从 PortletRequest Java 对象中检索它。下面是用来检索 LTPA 令牌和调用 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("

现在,您已经完成了单点登录 portlet。您可以构建项目,将该项目导出为 WAR 文件,并将它部署到 Lotus Workplace 服务器上。

用单点登录增强 Document Management portlet

在测试了上面所创建的新单点登录 portlet 之后,就可以开始增强本系列第 5 部分和第 6 部分中开发的 Document Management portlet 了。

添加单点登录功能的过程包含两个步骤。首先,需要添加一个函数,用该函数来连接使用 LTPA 令牌的 Content Manager 服务器。其次,需要修改 portlet 中的代码,其中用户和密码是从凭证保险库中检索获得的,将用于连接 Content Manager 服务器。

与 TConnect.java 示例相似,Document Management portlet 也有一个实用程序类,其中包含所有的连接和断开连接的函数。这个类就是 ICMConnectDisconnect。您需要将 TConnect.java 导入 com.ibm.bsd.util 包,并向 ICMConnectDisconnect.java 文件添加下列代码:

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;
}

为了定位需要进行修改的代码,可以搜索 getPassword4CMFromCredential,并用下列代码替换相关的代码:

...
//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) ;
...

现在,您应该可以使用 Document Management portlet 且无需维护用户名和密码了。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14751907/viewspace-591931/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14751907/viewspace-591931/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值