首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

打造 DB2 Content Manager 8.2 單點登入 Portlet:從配置到開發的完整指南

     編輯:DB2 教學

前言

在「雇員工作空間」系列的第 5、6 部分中,作者詳細介紹了如何建立 Document Management portlet 以存取 DB2 Content Manager。然而,這兩篇文章並未深入探討身份驗證機制。本文將補充說明 Document Management portlet 中實作的驗證方法,並示範如何改用輕量級第三方認證(LTPA)令牌來實現真正的單點登入(Single Sign-On,SSO)功能,讓使用者無需重複輸入帳號密碼即可無縫存取內容管理系統。

系統環境需求

本文實作環境包含以下產品版本:

  • 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 實際運行於 WebSphere Portal Server 之上,提供整合式企業工作環境,支援郵件、即時通訊與 portlet 應用程式。將 Document Management portlet 遷移至 Lotus Workplace 完全不需修改程式碼。

所有使用者資訊均儲存於 LDAP 使用者登錄表中,確保 Lotus Workplace 與 DB2 Content Manager 的使用者資料同步,這也是後續 LTPA 單點登入運作的必要條件。

傳統憑證保險庫機制與其缺失

DB2 Content Manager Server 作為後端服務與 portlet 整合,存取時需在伺服器端完成身分驗證。早期做法是透過 DB2 Content Manager API 使用使用者名稱與密碼連線,portlet 需提示輸入或使用儲存於 portlet 憑證保險庫(Credential Vault)中的憑證。

Document Management portlet 將使用者名稱、密碼等憑證儲存於各使用者的憑證保險庫中,並要求與使用者登錄表同步。這雖然隱藏了 DB2 Content Manager 的登入複雜度,但存在三大缺點:

  1. 需提供使用者介面讓使用者維護 DB2 Content Manager 憑證
  2. 當 portlet 與 Content Manager 共享同一使用者登錄表時,手動同步憑證極不便利
  3. 以明文帳號密碼形式暴露憑證,潛在安全風險

為規避上述問題,本文將介紹以 LTPA 令牌實現單點登入的完整方案。

LTPA 令牌單點登入原理

LTPA(Light-weight Third Party Authentication)令牌可在伺服器間提供單點登入。當配置 WebSphere Application Server 使用 LTPA 時,LTPA 令牌(本質為一 Cookie)將包含已驗證使用者的憑證資訊。

除了傳統的使用者名稱/密碼 Java API,DB2 Information Integrator for Content 還提供非視覺化(non-visual)的 CMBConnection bean,可直接使用 LTPA 令牌作為驗證憑證連線 DB2 Content Manager Server。此方式無需使用者手動維護憑證,亦不暴露帳號密碼,唯一前提是 Lotus Workplace 與 DB2 Content Manager 皆需支援 LTPA 令牌驗證。

配置 Lotus Workplace 與 DB2 Content Manager 實現 SSO

Lotus Workplace 2.0.1 配置

Lotus Workplace Server 運行於 WebSphere Portal Server 之上,後者又運行於 WebSphere Application Server。要為 Lotus Workplace 啟用單點登入,必須先啟用 WebSphere Application Server 的 SSO 功能。詳細步驟請參閱 Lotus Workplace Information Center 中的「Configuring Lotus Workplace products for seamless authentication」章節。

DB2 Content Manager 8.2 配置

需使用 Content Manager System Administration Client 在伺服器端完成以下設定:

  1. 啟用 Content Manager 伺服器的單點登入功能
  2. 建立新的權限集,包含 AllowConnectToLogon 與 AllowTrustedLogon 權限,以及其他必要權限(如 ClientPrint)
  3. 將新權限集指派給需透過 SSO 登入的使用者帳號
  4. 使用 eClient 驗證 SSO 功能是否正常運作

技巧:可對現有權限集右鍵選擇「Copy」,在保留原有權限基礎上新增所需權限,快速建立新權限集。

開發使用 LTPA 令牌的單點登入 Portlet

建立新 Portlet 專案骨架

於 WebSphere Studio Application Developer 中依序執行:

  1. File > New > Project,選擇 Portlet Development > Portlet Project
  2. 專案名稱輸入 CMSSO,類型選 Basic portlet,勾選 Configure advanced options
  3. EAR 專案名稱 CMSSOEAR,Content root 選 CMSSO,J2EE level 選 1.3 WebSphere Portal 5.0
  4. 於 Portlet Perspective 視圖中設定 Classpath Variable:
    • CMBROOT 指向 Content Manager 安裝路徑(如 X:\Program Files\IBM\CM82)
    • CMBHOME 指向 Content Manager 公共檔案目錄(如 X:\Program Files\IBM\CMgmt)
  5. 專案屬性中添加變數至 Java Build Path:CMBROOT/libcmb81.jar、CMBROOT/libcmbsdk81.jar、CMBHOME

整合範例 Java 程式進行測試

將 Content Manager 隨附的 TConnect.java 與 TListEntities.java 匯入專案 cmsso 套件並編譯。修改 CMSSOPortlet.java 的 actionPerformed() 方法呼叫 TListEntities.main() 以測試連線。匯出 WAR 檔部署至 Lotus Workplace Server,並將 Content Manager 公共目錄加入 Portal 類路徑(WebSphere 管理主控台 Environment > Shared Libraries > WPSLIB 的 CLASSPATH)。重啟伺服器後點擊 Submit 按鈕,若日誌輸出實體類型清單即代表基礎連線正常。

改寫連線邏輯以支援 LTPA 令牌

核心在於使用 CMBConnection bean 的 connectWithCredential() 方法,接受伺服器名稱、憑證物件、連線字串三個參數。以下為關鍵程式碼片段:

修改 TConnect.java 新增 connect() 方法

public static void connect(CMBConnection connection, String dstype,
    String server, String ltpaToken) throws Exception {
    // 解析伺服器名稱與連線字串
    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);
    }

    connection.setDsType(dstype);
    System.out.println("Connecting to server");
    connection.connectWithCredential(server, ltpaToken, "");
    System.out.println("OK, Connected");
    connection.setDisplayNamesEnabled(true);
}

修改 TListEntities.java 的 main() 方法

public static void main(String[] args) throws Exception {
    if (args.length < 3) { /* 印出語法說明並結束 */ }
    String dstype = args[0];
    String server = args[1];
    String ltpaToken = args[2];
    // ... 解析選用的 entity 參數 ...
    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);
}

於 CMSSOPortlet.java 中擷取 LTPA 令牌並呼叫

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();
            break;
        }
    }
}
String[] args = {"ICM", "ICMNLSDB", ltpaToken};
try {
    TListEntities.main(args);
} catch (Exception e) {
    e.printStackTrace(System.out);
}

完成建置、匯出 WAR、部署後,即擁有一個支援 LTPA 單點登入的 Portlet。

強化既有 Document Management Portlet 加入 SSO

測試無誤後,可著手改造系列文第 5、6 部分的 Document Management portlet。修改分兩步驟:

  1. 於工具類 ICMConnectDisconnect 中新增使用 LTPA 令牌連線的方法
  2. 將原本從憑證保險庫取得密碼並連線的程式碼,改為取得 LTPA 令牌並呼叫新連線方法

於 ICMConnectDisconnect.java 新增方法

public static DKDatastoreICM connectWithCredential(String userName, String ltpaToken)
    throws DKException, CMBException, Exception {
    PropertyResourceBundle bundle = (PropertyResourceBundle) PropertyResourceBundle.getBundle(BSDConstants.PROPERTY_FILE_NAME);
    String database = bundle.getString(BSDConstants.PROPERTY_DATABASE_NAME);
    CMBConnection connBean = new CMBConnection();
    connBean.setUserid(userName); // 某些 CM 作業需用 userid
    System.out.println("Connecting to datastore (Database '" + database + "', LtpaToken '" + ltpaToken + "')");
    TConnect.connect(connBean, "ICM", 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();
                break;
            }
        }
    }
    return ltpaToken;
}

替換原連線邏輯

搜尋 getPassWord4CMFromCredential,將相關程式碼替換為:

// 取得 Portal 使用者 ID
String userId = request.getUser().getUserID();
// 不再從憑證保險庫取密碼
String passWord = "";

// 使用 LTPA 令牌連線
String ltpaToken = ICMConnectDisconnect.getLtpaToken(request);
DKDatastoreICM store = ICMConnectDisconnect.connectWithCredential(userId, ltpaToken);
// DKDatastoreICM store = ICMConnectDisconnect.connect(userId, passWord);
sessionBean.setDataStore(store);

完成部署後,Document Management portlet 即可在無需維護帳號密碼的情況下實現單點登入。

結語

Content Manager 伺服器與 portlet 的無縫整合對企業客戶至關重要。本文詳細闡述了兩種整合驗證方式的差異,並提供從伺服器配置到 Portlet 開發、既有應用改造的完整實作指南,助您打造安全、便捷的單點登入體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved