通过 InfoSphere Federation Server 使用 LDAP 包装器

在 SQL 环境中利用并集成您的目录数据

LDAP 包装器是一个基于 InfoSphere™ Federation Server Java 包装器 SDK 技术的纯 Java™ 包。在 SQL 环境中通过为轻量级目录访问协议(LDAP)目录服务器提供只读访问,LDAP 可以促进关系数据库中的业务数据和 LDAP 目录服务器中的人力资源数据之间的集成和连接。

Yun Feng Sun, 顾问软件工程师, IBM

Sun Yun Feng 的照片Yun Feng Sun 是 IBM 中国软件开发实验室的顾问软件工程师。他当前为 IBM InfoSphere Federation Server 产品的开发团队工作。



Eileen Lin, 高级技术人员, IBM

Eileen Lin 博士是加利福尼亚 San Jose 的 IBM Silicon Valley Laboratory 的高级技术人员。她是负责 DataJoiner 的最初成员之一,DataJoiner 是一种联合数据库产品,是 DB2 中的联合技术的前身。现在,她是 WebSphere Federation Server 的首席架构师。Lin 博士拥有许多专利,这些专利涵盖很多领域,如联合技术、查询优化和并行查询处理。



Art Kaufmann, 高级软件工程师, IBM

Art Kaufmann 照片Art Kaufmann 是从事通过联合与 Web 服务集成信息的高级软件工程师。Art 是 SOA 和 Federation 团队的技术领导,负责包装器 SDK。



Martin Klumpp, 技术主管、软件工程师, IBM

Martin Klumpp 的照片Martin Klumpp 是 InfoSphere FastTrack 产品的技术主管,居住在加利福尼亚 San Jose 的 IBM Silicon Valley Laboratory。他在 2005 年参与了 LDAP 包装器的设计和开发。


developerWorks 投稿作者

Xing Yu Liu, 软件工程师实习生, IBM

Xing Yu Liu 的照片Xing Yu Liu 是 IBM 中国软件开发实验室的软件工程师实习生,参与了 LDAP 包装器的开发。



2011 年 1 月 06 日

在开始之前

关于此教程

本教程介绍了基于 Java 的 LDAP 包装器,其可以帮助 InfoSphere Federation Server 访问并集成 LDAP 目录数据。本教程开始先着重讲述该包装器的业务价值,然后说明使用该包装器的详细步骤,接下来是一个简单的场景,将 LDAP 数据与其他企业数据联接。LDAP 包装器的二进制代码可在 下载 部分下载。

目标

本教程向您展示了如何配置 LDAP 包装器并将其与 InfoSphere Federation Server 配合使用,来读取 LDAP 目录服务器中的目录数据。在您完成了此操作以后,就可以将 LDAP 目录服务器中的数据与您的联合数据库可以访问的其他企业数据联接并统一。

先决条件

本教程是使用 InfoSphere Federation Server 和 LDAP 目录服务器编写的。您应该已经对 LDAP、关系数据库和 InfoSphere Federation Server 概念(包括联合服务器、包装器、服务器定义、用户映射和昵称)有一般性了解。

系统要求

要完成本教程中的步骤,您需要安装如下软件:

  • InfoSphere Federation Server:本教程是基于 InfoSphere Federation Server 9.5 的。也可以使用 InfoSphere Federation Server v9.1 和 v9.7。更多细节,请参考 InfoSphere Federation Server 网站
  • LDAP 目录服务器:本教程是基于 Tivoli Directory Server V6.0 的。更多细节,请参考 Tivoli Directory Server 网站。但是,也可以使用任何兼容 LDAP v3 的 LDAP 目录服务器。

介绍

如今,任何最简单的业务任务都需要来自各种多年来企业建立起来的数据源的信息。数据可存储为各种格式,如关系或非关系数据源。这种复杂和动态的环境对业务用户和应用程序,以及那些必须维护并管理这种环境的 IT 人员提出了重大的挑战。联合技术可以保护来自与访问各种位置的数据相关联的复杂事物的请求者,包括连接性、语义、格式和访问方法。使用基于标准的语言,如结构化查询语言(Structured Query Language,SQL),InfoSphere Federation Server 可使用户或应用程序能够代表它们操作,并可透明地访问信息而无需关心其物理实现。

通过使现有联合技术能够访问并集成 LDAP 目录服务器中的数据,LDAP 包装器增加了现有联合技术的价值,LDAP 目录服务器广泛地应用在企业环境中以便存储人力资源数据和身份信息。它是基于 InfoSphere Federation Server Java 包装器 SDK 技术通过纯 Java 开发的。在内部它使用 JNDI 来访问 LDAP 目录服务器。

图 1 显示了 LDAP 包装器的体系结构。

图 1. LDAP 包装器的体系结构
联合客户端使用 SQL 来访问联合服务器,其使用 LDAP 包装器和 JNDI 来访问 LDAP Server。客户端上的结果是一个关系表。

轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP)是一种用于查询和修改目录服务的应用程序协议。存储在目录中的基本信息单位被称为 LDAP 条目,其通过 LDAP 架构定义并组织为目录信息树(Directory Information Tree,DIT)结构。LDAP 条目可通过其专有名称(Distinguished Name,DN)标识。

图 2 显示了示例部门条目,其存储在 DIT 中。对象类是 department,DN 是 ou=IBM(ou:组织单位)。

图 2. LDAP DIT 示例
图表显示 ou=IBM,连接到 4 个部门:质量保证、开发、市场以及销售,其中每一个部门都包括员工、国家和位置

通过 LDAP 包装器,您可以将具有相同架构的 DN 下的 LDAP 条目映射到 LDAP 昵称。然后可以通过 InfoSphere Federation Server 使用 SQL 来查询 LDAP 昵称上已映射的 LDAP 条目。基本上,您可以通过指定 DN 和 LDAP 条目的对象类来执行映射。例如,如果您已经创建了具有如图 2 所示的 DIT 的昵称 DEPARTMENT,则您可以使用如清单 1 所示的 SQL 来检索所有少于 20 名员工的部门。

清单 1. 查询昵称 DEPARTMENT
SELECT * FROM DEPARTMENT WHERE EMPLOYEES < 20;

NAME        EMPLOYEES   COUNTRY   LOCATION
----------  ----------- --------- ---------
Marketing   12          USA       CA 
Sales       10          USA       CA

本教程为您提供有关如何使用 LDAP 包装器的详细介绍。


部署 LDAP 包装器

下载 LDAP 包装器包

LDAP 包装器可在本教程的 下载 部分中找到。下载 LDAPWrapper.zip 到您的本地文件系统上并将其解压到一个目录中。此压缩文件包含以下文件:

  • LDAPWrapper.jar 是 LDAP 包装器的 Java 包。将 jar 文件放置在 <InfoSphere Federation Server install path>/function 目录中。此目录位于 InfoSphere Federation Server JVM 的默认类路径上。或者,您可以将包放在您想要的任何路径上,并更新您的 CLASSPATH 环境变量以便包括该路径。
  • DB2 控制中心使用 LDAPWrapper.xmlLDAPWrapper.properties 来定义控制中心中的 LDAP 包装器对象。将 LDAPWrapper.xml 放置在 <InfoSphere Federation Server install path>/cfg 目录中。将 LDAPWrapper.properties 放置在 <InfoSphere Federation Server install path>/tools/en_US/wrapper_cfg 目录中。
  • create_function_mappings.ddl 包含一个 DDL 语句,用于为 LDAP 包装器创建了一个函数映射。稍后在本教程中您将使用此 ddl 文件。

为 LDAP 包装器设置 dbm cfg 参数

LDAP 包装器是一个基于 Java 的包装器,其使用 JDNI 来连接 LDAP 目录服务器。Java 2 SDK V1.4.2 及以上版本都包括 JNDI 类库以及 LDAP 包装器使用的一些功能。使用 InfoSphere Federation Server 附带的 JDK。

要为 LDAP 包装器设置 dbm cfg 参数,需要执行以下步骤:

  1. 设置名为 JDK_PATH 的数据库管理器配置参数来指向一个有效 JDK 安装。

    如果 JDK 是与您的 InfoSphere Federation Server 产品一起安装的,则正确设置了此参数。然而,如果您重新设置数据库管理器 (dbm cfg) 参数,则您需要指定 Java 的 SDK 的安装位置。要执行此操作,要使用清单 2 中的命令,并使用您的 JDK 的实际路径替换 <your_jdk_path >

    清单 2. 更新 JDK PATH
    db2 update dbm cfg using JDK_PATH <your_jdk_path>

    如果您的 JDK 被安装在 $HOME/sqllib/java/jdk 目录中,则您可以定义路径为一个空字符串 ('')。

  2. 增加 Java VM 的堆大小。

    在默认情况下,在 HP-UX 上将 Java VM 堆大小设置为 4096 页 (4K),而在 InfoSphere Federation Server V9.5 上的所有其他操作系统中为 2048 页。这可能不足以装载并运行 LDAP 包装器,因此您应该增加堆大小。

    例如,运行清单 3 中的命令以便将您的 Java VM 堆大小设置为 8192 页:

    清单 3. 更新 Java 堆大小
    db2 update dbm cfg using JAVA_HEAP_SZ 8192
  3. 在您更新了数据管理器配置以后,您必须使用如清单 4 中所示的命令来重新启动 DB2。
    清单 4. 重新启动 DB2
    db2 terminate
    db2stop
    db2start

将 LDAP 数据源添加到联合服务器

要配置联合服务器来访问 LDAP 数据源,您必须为联合服务器提供关于您想要访问的数据源和对象的信息。通过使用 DB2 控制中心或 DB2 命令行,您可以配置联合服务器来访问 LDAP 数据源。DB2 控制中心包括一个配置联合服务器的向导。

在您开始以前

  • 必须在一台将要作为联合服务器的服务器上安装 Federation。
  • 联合服务器上必须有数据库。

要将 LDAP 目录服务器和 LDAP 对象添加到联合服务器上,请执行如下步骤:

  1. 为 LDAP 包装器注册自定义函数。
  2. 注册 LDAP 包装器。
  3. 注册 LDAP 服务器定义。
  4. 可选:创建 LDAP 用户映射。
  5. 为 LDAP 条目注册昵称。

为 LDAP 包装器注册自定义函数

在您注册 LDAP 包装器以前,您必须先注册 LDAP 自定义函数。LDAP 自定义函数必须与 LDAP 包装器配合使用来将谓词推入 LDAP 目录数据源服务器上的查询引擎。

您必须在安装了 LDAP 包装器的每一个联合数据库实例上注册所有自定义函数。LDAP 包装器的所有自定义函数必须与架构名称 ldap 一起注册。对于每一个 LDAP 自定义函数来说,发布带有 AS TEMPLATE DETERMINISTIC NO EXTERNAL ACTION 关键字的 CREATE FUNCTION 语句。每一个函数的完全限定名称是 ldap.function_name

清单 5 所示的示例注册一个 ldap.search_dn 函数:

清单 5. 创建函数模板示例
CREATE FUNCTION ldap.search_dn (varchar(),varchar()) 
    RETURNS INTEGER AS TEMPLATE 
    DETERMINISTIC NO EXTERNAL ACTION;

要注册自定义函数,您可以使用来自下载包的示例文件 create_function_mappings.ddl,其包括每一个可能的数据类型组合的 CREATE FUNCTION 语句。然后您可以连接联合数据库并在每一个联合数据库上使用清单 6 中的命令来注册自定义函数。

清单 6. 注册 LDAP 包装器自定义函数
db2 connect to <federated database>

db2  -tvf create_function_mappings.ddl

LDAP 搜索使用两种函数类型:

  • 搜索配置函数
  • 搜索筛选器函数

本教程的后半部分将向您展示如何使用这些函数。

表 1 和表 2 列出了与 LDAP 包装器配合使用的自定义函数的描述。

表 1. LDAP 搜索配置参数的自定义函数
函数描述
ldap.search_dn(arg1,arg2)agr1 指定任一将要应用变更的昵称的列名称。
arg2 指定 LDAP 搜索基对象 - DIT 上的搜索开始点。
在使用此函数来查询 LDAP 昵称时,它将覆盖在该昵称上已定义的 DN 选项。
ldap.search_scope(arg1,arg2)agr1 指定任一将要应用变更的昵称的列名称。
arg2 指定 DIT 内从基对象开始的搜索深度。

参数值可以是下列选项之一:

  • OBJECT—仅搜索基对象。
  • ONELEVEL—仅搜索基对象的直接子级;没有检查基对象本身。
  • SUBTREE—搜索基对象及其所有后代。

注意:对于表 1 中的两个函数来说,arg1 参数的数据类型是 LDAP 包装器支持的任一数据类型。arg2 参数的数据类型是 varchar()。

表 2. LDAP 搜索筛选器的自定义函数
函数描述
ldap.eq(arg1,arg2)LDAP 搜索筛选器中的运算符 =
ldap.ge(arg1,arg2)LDAP 搜索筛选器中的运算符 >=
ldap.le(arg1,arg2)LDAP 搜索筛选器中的运算符 <=
ldap.gt(arg1,arg2)在 LDAP 搜索筛选器中,没有直接的 > 运算符。gt 函数将被转换为 &( arg1>=arg2)(! (arg1=arg2))
ldap.lt(arg1,arg2)在 LDAP 搜索筛选器中,没有直接的 < 运算符。lt 函数将被转换为 &( arg1<=arg2)(! (arg1=arg2))

注意:

对于表 2 中所列出的函数来说,arg1arg2 具有相同的数据类型。这些是 LDAP 包装器支持的数据类型,除 BLOBCLOBarg1 指定列的名称。arg2 指定要进行对比的值。对于 ldap.eq 来说,如果远程 LDAP 属性语法支持子字符串匹配,则 * 字符可用于 arg2 并匹配任何子字符串。

对于代表多值属性的列来说,可检索到具有任何匹配值的条目,且所有的值都与可显示的昵称列选项 DELIMITER 值连接在一起。

注册 LDAP 包装器

您必须注册一个包装器来访问 LDAP 数据源。联合服务器使用包装器来与数据源通信并检索其中数据。

要注册一个包装器,请使用 CREATE WRAPPER 语句。例如,要在使用 AIX 操作系统的联合服务器上注册 ldap_wrapper,请发布清单 7 中的语句。

清单 7. 创建包装器语句
CREATE WRAPPER ldap_wrapper LIBRARY 'libdb2qgjava.a' options( 
    UNFENCED_WRAPPER_CLASS 'com.ibm.wfs.wrapper.ldap.UnfencedLdapWrapper');
  • LIBRARY 'libdb2qgjava.a'

    这是使用 AIX 操作系统的联合服务器的 Java 包装器 SDK 库文件的名称。用于 Windows 平台上的库名称是 'db2qgjava.dll'。用于 AIX 上的库名称是 'libdb2qgjava.a',而在其他 UNIX 平台上的库名称是 'libdb2qgjava.so'

  • UNFENCED_WRAPPER_CLASS 'com.ibm.wfs.wrapper.ldap.UnfencedLdapWrapper'

    对于任何基于 Java 的包装器来说,UNFENCED_WRAPPER_CLASS 包装器选项都是必需的,其指向不加隔离包装器类的 LDAP 包装器名称。

为 LDAP 数据源注册服务器定义

在您注册包装器以后,您必须注册一个相应的服务器。

对于 LDAP 包装器来说,您要创建一个服务器定义,因为该包装器必须提供连接信息,此连接信息可用于连接 LDAP 目录数据源服务器。

要为联合系统注册 LDAP 服务器定义,请使用 CREATE SERVER 语句。

服务器对象必须与通过使用 CREATE WRAPPER 语句注册的 LDAP 包装器关联。

例如,假设您想要为与联合服务器位于同一机器上的 LDAP 目录数据源服务器创建一个名为 ldap_server 的服务器对象,从而监听端口 389。与 LDAP 目录数据源服务器的通信是不加密的,且连接超时被设置为 3 分钟。您可以使用如清单 8 中所示的 CREATE SERVER 语句来注册服务器对象。

清单 8. 创建服务器语句
CREATE SERVER ldap_server WRAPPER ldap_wrapper 
   OPTIONS (URL 'ldap://localhost:389', TIMTOUT ‘3');

您可以使用在 CREATE SERVER 语句中指定的 URLTIMEOUT 服务器选项,如表 3 所示。

表 3. LDAP 服务器选项
服务器选项描述
URL必需
类型:字符串
这是 LDAP 目录数据源服务器的连接 URL
TIMEOUT可选
类型:字符串。其必须是一个整数字符串。
连接的超时值(LDAP 绑定操作)以分钟计。
默认值是 2 分钟。

URL 选项值格式

您可以使用明确的主机列表或默认主机来指定一个或多个目标 LDAP 目录服务器。

  • 显式主机列表

    您可以显式指定 LDAP 目录数据源服务器运行所在主机的名称。您可以使用 URL 选项来连接空白分隔的主机列表,且每一台主机都可选择使用形式 scheme://host:portscheme://host。清单 9 中的示例显示了 LDAP 包装器如何连接到列表中的第一台活动服务器。

    清单 9. 服务器 URL 选项中的显式主机列表
    CREATE SERVER ldap_server WRAPPER ldap_wrapper 
       OPTIONS ( URL 'ldap://server1');
       
    CREATE SERVER ldap_server WRAPPER ldap_wrapper 
       OPTIONS ( URL 'ldap://server1:389');
       
    CREATE SERVER ldap_server WRAPPER ldap_wrapper 
       OPTIONS ( URL 'ldap://server1:389 ldap://server2');
  • 默认主机

    如果您已经在您的网络基础设施中的 DNS 上注册了 LDAP 服务,则借助 JNDI 的帮助,LDAP 包装器可通过以下格式放置一个或多个默认 LDAP 目录数据源服务器:

    清单 10. 服务器 URL 选项中的默认主机
    CREATE SERVER ldap_server WRAPPER ldap_wrapper OPTIONS (URL 'ldap://');

    如果将主机参数设置为 ldap://,则 LDAP 库将会尝试寻找一个或多个具有非 SSL 端口的默认 LDAP 目录数据源服务器。如果其发现多个默认服务器,则会按顺序处理清单直到其发现一个活动服务器为止。

    您可以将专有名称作为筛选器添加到 URL,以便基于服务器的后缀选择 LDAP 目录数据源服务器。在规范化案例以后,如果 DN 的主要部分与服务器后缀精确匹配,则它会将该服务器添加到候选服务器的列表中。例如,清单 11 显示了可返回默认 LDAP 数据源服务器(具有仅支持已指定 DN 的后缀)的语句。

    清单 11. 服务器 URL 选项中带有后缀的默认主机
    CREATE SERVER ldap_server WRAPPER ldap_wrapper 
       OPTIONS (URL 'ldap:///cn=fred, dc=austin, dc=ibm, dc=com’);

    该服务器具有与搜索参数相匹配的后缀 dc=austindc=ibmdc=com。如果找到多个默认服务器,则会按顺序处理该列表直到发现活动服务器为止。

LDAP 包装器保持与已选择的 LDAP 目录数据源服务器连接在一起,直到清除该连接为止。

TIMEOUT

如果在某种超时期间内 LDAP 包装器不能建立到 LDAP 目录数据源服务器的连接,则其终止连接尝试。通过 LDAP 包装器设置的默认超时期间是两分钟。通过将选项值设置为一串代表在几分钟内连接超时的整数,您可以变更超时期间。

LDAP 包装器安全模型

LDAP 包使用 JNDI 安全性,其是基础 Java 平台和 LDAP 协议中的安全模型。将使用 SSL 加密,作为提前条件,必须为 SSL 配置 LDAP 目录数据源服务器。SSL 证书必须在 Federation Server JRE 中注册。随后您必须在受信任证书的 Federation Server JRE 数据库中安装该服务器或 CA 证书。例如,清单 12 显示了如何将证书添加到 JRE。

清单 12. 将证书添加到 JRE
cd <Federation_Server_JRE_PATH>/lib/security
keytool -import -file server_cert.cer -keystore cacerts

要获得有关注册 SSL 证书的更多信息,请参考 JDK 文档。

您可以从 LDAPS URL 请求 SSL。如果 LDAPS URL 位于 URL 选项的架构部分中,则它是 ldaps 而不是 ldap。在与 LDAP 目录数据源服务器通信时,它指定使用 SSL。例如,清单 13 显示了 LDAP 包装器如何将 SSL 与 CREATE SERVER 语句配合使用。

清单 13. 启用 SSL 的创建服务器语句
CREATE SERVER ldap_server WRAPPER ldap_wrapper 
   OPTIONS ( URL 'ldaps://localhost:636', TIMEOUT ‘3’);

注意:必须使用 SSL 连接到使用 SSL 的端口上的服务器。默认的 LDAP SSL 端口是 636,不安全通信的默认端口是 389

为 LDAP 数据源创建用户映射

在您尝试访问 LDAP 目录数据源服务器时,联合服务器建立了一个到 LDAP 目录数据源服务器的连接。您可能不必创建用户映射,具体取决于您的 LDAP 系统中使用的帐户访问方法。

用户映射是每一个联合服务器用户 ID 和密码之间,以及相应数据源用户 ID 和密码之间的关联。

通过联合系统您可以使用两种方法来指定用户映射。您可以包括外部存储库(如另外一个 LDAP 目录服务器)以便存储用户映射,或者您可以在联合数据库目录中创建用户映射。

  • 如果您的 LDAP 目录数据源服务器是配置进行匿名访问的,则您不必在 InfoSphere Federation Server 上创建用户映射。

  • 如果您有外部存储库(如另外一个 LDAP 目录服务器)存储用户映射,则您不必创建用户映射,但是当您注册或变更包装器或服务器时,您必须在 LDAP 包装器或 LDAP 服务器定义中指定 DB2_UM_PLUGIN 选项。

  • 如果您的 LDAP 目录数据源服务器被配置用于通过 ID 和密码验证用户帐户,则您必须为使用 LDAP 包装器的任一帐户创建用户映射。

用户映射为验证用户或应用程序的访问提供了一种方式,即通过 LDAP 包装器查询 LDAP 数据源。如果用户或应用程序将 SQL 查询提交给已注册的 LDAP 昵称,且没有为此用户或应用程序定义用户映射,则 LDAP 包装器会使用匿名验证来检索来自远程 LDAP 目录数据源服务器的数据。如果 LDAP DIT 被查询且需要验证,则可能返回错误消息。要确保传递正确的用户 ID 和密码到 LDAP 目录数据源服务器,您可以在联合数据库中为被授权搜索 LDAP 数据源的用户创建用户映射。在您创建用户映射时,在联合数据库系统目录表中用加密的格式存储密码。

使用 CREATE USER MAPPING 语句来为 LDAP 服务器对象注册用户。用户对象必须与通过使用 CREATE SERVER 语句注册的 LDAP 服务器对象关联。例如,清单 14 显示了 CREATE USER MAPPING 语句如何将用户 DEMO 映射到 LDAP 目录数据源服务器上的用户 cn=root

清单 14. 为特定用户创建用户映射语句
CREATE USER MAPPING FOR DEMO SERVER ldap_server OPTIONS (
   REMOTE_AUTHID 'cn=root',
   REMOTE_PASSWORD 'amIAdmin');

在清单 15 所示的示例中,标识当前用户的关键字是 USER ,而不是 USER 的用户名。

清单 15. 为当前用户创建用户映射语句
CREATE USER MAPPING FOR USER SERVER ldap_server OPTIONS (
   REMOTE_AUTHID 'cn=root',
   REMOTE_PASSWORD 'amIAdmin');
表 4. LDAP 用户映射选项
用户映射选项描述
REMOTE_AUTHID必需
类型:非零长度字符串
可用于连接 LDAP 目录服务器的远程用户 ID
REMOTE_PASSWORD必需
类型:非零长度字符串
属于用户 ID 的远程密码

为 LDAP 数据源注册昵称

在您注册服务器以后,您必须注册相应的昵称以便在查询中指参考 LDAP 条目。

要定义 LDAP 昵称,您必须针对关系模型映射 LDAP 条目属性。昵称列名称需要匹配 LDAP 条目属性名称。可将 LDAP 属性类型映射到以下 DB2 数据类型:VARCHARCHARACTERCLOBINTEGERSMALLINTBIGINTDOUBLE/FLOATREALDECIMAL/NUMERICTIMESTAMPTIMEDATE 以及 BLOB

属性数据类型应该是相同或兼容的,以便 LDAP 包装器可以将属性数据转换为 DB2 数据类型。如果 LDAP 目录数据源服务器存储了具有兼容格式的字符串类型,则 LDAP 包装器可将该数据设置为 DB2 数据类型。如果不能正确设置数据,或者在检索来自数据源的数据时超出 DB2 数据类型的范围,则包装器将报告错误。如果非数值字段对于其列类型来说太长,则多余数据的将被截断并伴有警告消息。如果十进制字段在基数字符后的数位比其列类型尺度参数允许的多,则多余数据将被截断并伴有警告消息 (SQL1844W)。

表 5. DB2/LDAP 数据类型映射表
DB2 数据类型LDAP 属性数据格式
VARCHARCHARACTERCLOB任何在本质上具有字符串语法的 LDAP 属性
INTEGERSMALLINTBIGINT
  • 具有 INTEGER 语法 (1.3.6.1.4.1.1466.115.121.1.27) 的 LDAP 属性
  • 具有使用整数格式字符串数据的 LDAP 属性
DOUBLE/FLOATREAL具有使用浮点数格式字符串数据的 LDAP 属性
DECIMAL/NUMERIC具有使用在昵称中定义的十进制/数字格式字符串数据的 LDAP 属性
TIMESTAMP具有通用时间 (1.3.6.1.4.1.1466.115.121.1.24) 的 LDAP 属性
DATE具有通用时间 (1.3.6.1.4.1.1466.115.121.1.24) 的 LDAP 属性。
LDAP 包装器提取 LDAP 属性值的 DATE 部分并将其转换为 DB2 DATE 格式。
TIME具有通用时间 (1.3.6.1.4.1.1466.115.121.1.24) 的 LDAP 属性。
LDAP 包装器提取 LDAP 属性值的 TIME 部分并将其转换为 DB2 TIME 格式。
BLOB任何在本质上具有二进制语法的 LDAP 属性

要注册 LDAP 昵称,请使用 CREATE NICKNAME 语句。例如,清单 16 显示了该语句如何创建 Department 昵称。

清单 16. 创建昵称语句
CREATE NICKNAME Department (
   department VARCHAR(20) NOT NULL, 
   name VARCHAR (150),
   employees INTEGER,
   country VARCHAR(50),
   location VARCHAR(10)) 
   FOR SERVER ldap_server 
      OPTIONS (
         DN 'ou=IBM'
         OBJECTCLASS 'department'
         SCOPE ‘ONELEVEL’
         SIZE_LIMIT '1000'
         TIME_LIMIT '10'
         DEREF ‘FINDING’);

LDAP 包装器针对 LDAP 搜索操作的 LDAP 昵称翻译所有查询。表 6 显示了指定的 LDAP 昵称选项如何与 LDAP 搜索参数对应。

表 6. LDAP 昵称选项
昵称选项描述
DN必需
类型:String
在 LDAP 搜索的 DIT 中,专有名称指定基对象。
OBJECTCLASS必需
类型:String
通过给定上下文的昵称指定可检索的条目的对象类。它允许通过分号 ; 隔开多个值。
SCOPE可选
类型:String
指定在 DIT 内从基对象开始的搜索深度。该值可以是下列选项之一:
  • OBJECT—仅搜索基对象。
  • ONELEVEL—仅搜索基对象的直接子级;没有检查基对象本身。
  • SUBTREE—搜索基对象及其所有后代。这是默认的搜索范围。
SIZE_LIMIT可选
类型:String。它必须是整数字符串。
限制从搜索返回的条目数量。
默认值是 0,因此搜索结果没有最大返回限制。
TIME_LIMIT可选
类型:String。它必须是整数字符串。
将搜索的总时间限制在几分钟以内。
默认值是 0,因此搜索没有时间限制。
DEREF可选
类型:String
指定是否在搜索期间处理别名对象(如 X.501 所定义的)。如果此选项值被设置为 Y,则在搜索期间数据源将不会参考附属的基对象。
默认值是 N

DN

专有名称(DN)为 LDAP 搜索上下文指定 Base 参数。基对象是在 DIT 内定义搜索开始点的节点。

在查询昵称时,您可以通过两种方式更改 DN 值:

  • 在查询以前使用 ALTER NICKNAME 语句来更改 DN
  • 在谓词中使用 ldap.search_dn 函数以便覆盖昵称中指定的 DN 值。清单 17 显示了一个示例查询。
    清单 17. 通过 ldap.search_dn 查询
    select * from department where ldap.search_dn (department.name,‘cn=dev,ou=ibm’)=1;

OBJECTCLASS

对象类是一个 LDAP 术语,描述通过目录条目表示的对象类型。OBJECTCLASS 选项用于执行以下任务:

  1. 指定可以检索何种类型的条目。例如:搜索上下文包含来自结构化对象类 PersonDepartment 的条目。因此,在您搜索昵称时,根据在 CREATE NICKNAME 语句中如何指定的 OBJECTCLASS,将返回 PersonDepartment 对象类实例。

  2. 强制执行昵称列名称。在 CREATE NICKNAME 语句中的列名称应该是在对象类或其高级对象类中指定的属性名称。如果您想定义不同于 LDAP 属性名称的昵称列名称,必须使用 REMOTE_NAME 列选项来注册昵称。例如,清单 18 显示了如何通过不同的名称 mployee_number 定义员工属性。

    清单 18. 通过列选项 MOTE_NAME 创建昵称
    CREATE NICKNAME Department (
       department VARCHAR(20) NOT NULL, 
       name VARCHAR (150),
       employee_number INTEGER OPTIONS(REMOTE_NAME ’ employees’),
       country VARCHAR(50),
       location VARCHAR(10)) 
       FOR SERVER ldap_server 
       OPTIONS (
           DN 'ou=IBM'
           OBJECTCLASS 'department');

虽然可以通过在 LDAP 目录数据源服务器中定义的任一有效对象类名称定义 OBJECTCLASS 值,但是其在名称中不包含 *

在 LDAP 系统中您可以将对象类声明为抽象、结构或辅助的。您可以使用抽象对象类作为创建其他对象类的平台。目录条目无法从抽象对象类获得证明;而它需要结构对象类。虽然辅助对象类无法通过其自身作为目录条目来获得证明,但是其可被附加到从结构对象类证明的目录条目中。辅助对象类提供一种在不变更结构类结构定义的情况下扩展结构对象类的方法。

清单 19 显示了 LDAP 条目的示例。

清单 19. 具有辅助对象类的示例 LDAP 条目
dn: cn=Barbara J Jensen,dc=example,dc=com
objectClass: person 
objectClass: contact
cn: Barbara J Jensen
sn: Jensen
mail: jensen@example.com

称为 person 的 objectClass 是结构对象类,因此其具有 cnsn 属性。

称为 contact 的 objectClass 是辅助对象类,因此其具有称为 mail 的属性。

通过将辅助对象类中的属性与同一条目中的结构或其他辅助对象类中的属性合并在一起,您可以检索辅助对象类中的属性。通过分号 ; 分隔符,OBJECTCLASS 允许多个值。

例如,清单 20 显示了如何使用多个对象类来创建昵称。

清单 20. 通过多个对象类创建昵称
CREATE NICKNAME ldap_person_mail (
   cn char(50) NOT NULL, 
   sn char(30), 
   mail char(50)) 
   FOR SERVER ldap_server 
      OPTIONS (
          DN 'dc=example.com’, 
          OBJECTCLASS 'person;contact');

SCOPE

您可以为每一个 LDAP 搜索查询设置 OBJECTONELEVELSUBTREE 搜索范围。在查询昵称时,您可以使用以下两种方式来变更 SCOPE 值。

  • 在查询以前,您可以使用 ALTER NICKNAME 语句来变更 SCOPE 值。

  • 您可以在谓词中使用 ldap.search_scope 函数,以便 ldap.search_scope 函数覆盖在昵称中指定的 SCOPE 值。例如,清单 21 显示了如何通过 ldap.search_scope 函数进行查询。

    清单 21. 通过 ldap.search_scope 进行查询
    SELECT * FROM Department WHERE LDAP.SEARCH_SCOPE (Department.name,'SUBTREE') = 1;

TIME_LIMITSIZE_LIMIT

当您在 LDAP 昵称上设置查询时,其会被转化为 LDAP 搜索操作。由于常规 LDAP 搜索返回大量的条目,所以您应该指定时间和大小的限制以便避免消耗资源。SIZE_LIMIT 限制了搜索的返回条目数量。TIME_LIMIT 限制了搜索的总时间。LDAP 目录数据源服务器也可能比 LDAP 包装器所要求的还要严格。因此,实际的 TIME_LIMITSIZE_LIMIT 是此选项中指定的较小值,以及 LDAP 目录数据源服务器中配置的值。

注意:在您查询 LDAP 昵称时,SIZE_LIMIT 并不意味着限制 LDAP 包装器返回的行数量。此外,它也为 LDAP 查询的 LDAP 搜索操作设置大小限制参数以便检索来自 LDAP 目录数据源服务器的数据。类似的情况下,您可以使用 TIME_LIMIT 来为 LDAP 搜索设置时间限制参数。

如果您设置太高的限制,则 SIZE_LIMITTIME_LIMIT 选项可能给出非确定查询结果。例如,清单 22 显示了如何通过特定大小和时间限制来查询昵称。

清单 22. 通过 SIZE_LIMIT 和 TIME_LIMIT 查询昵称
CREATE NICKNAME department (
    department VARCHAR(20) NOT NULL, 
    name VARCHAR (150),
    employees INTEGER,
    country VARCHAR(50),
    location VARCHAR(10)) 
    FOR SERVER ldap_server 
    OPTIONS (
         DN 'ou=IBM'
         OBJECTCLASS 'department'
         SIZE_LIMIT '1000'
         TIME_LIMIT '10');
         
SELECT * FROM department WHERE location=’CA';

如果您将 DN ou=ibm 下的对象类 department 设置为 1000 个条目的 SIZE_LIMIT,而实际上会有超过 1000 个条目,则该查询可能会返回不同数量的行。这种情况的发生是因为一些匹配了标准 location=CA 的条目可能无法从 LDAP 目录数据源服务器检索。

为 LDAP 包装器定义多个值属性

通过将每个属性定义为其真的对等 DB2 数据类型,您可以最大化 LDAP 包装器的查询功能,其中 LDAP 整数将定义为 DB2 整数。然而,通过进行此操作,您阻止为非 VARCHAR 属性返回多个值,因为只返回第一个值。这是被限制的,因为在您选择具有多个值的属性时,每一个 LDAP 条目该包装器只返回一行结果。然而,您可以通过 VARCHAR 数据类型为同一远程属性定义另一列。通过使用 REMOTE_NAME 列选项,您可以指定第二列的远程名称。

可以使用 SELECT 列表中的列名称来以分隔符分隔的列表形式返回所有值。您可以在每一列的 DELIMITER 选项内指定要使用的分隔符。

您还可以标准化每一个多值列的本地名称。例如,您可以将 m_ 前缀添加到列的本地名称中,该列的本地名称被定义为真实数据类型。例如,假设您在通过数据类型 TIMESTAMP 定义的 LDAP 多值属性中具有名为 actionDate 的昵称列。您可以创建名为 m_actionDate 的第二昵称列,其具有指向 actionDateREMOTE_NAME 列选项。然后您可以定义它作为 VARCHAR 数据类型,并在 SELECT 清单中使用 m_actionDate 以便在分隔符分隔的列表中返回所有审批日期。例如,清单 23 显示了如何通过使用多值属性创建昵称。

清单 23. 为多值属性创建昵称
CREATE NICKNAME date (
     actionDate  TIMESTAMP,
     m_actionDate  VARCHAR(256) OPTIONS (REMOTE_NAME 'actionDate', DELIMITER  ';')) 
     FOR SERVER ldap_server
     OPTIONS (
        DN 'ou=IBM'
        OBJECTCLASS 'date');

LDAP 数据源的查询和自定义函数

在查询中您可以使用自定义函数。

LDAP 搜索配置参数的自定义函数

根据查询,您可以变更昵称的搜索 DNSCOPE。您可以使用以下两种自定义函数来为查询临时设置值:

  • ldap.search_dn
  • ldap.search_scope

在您使用自定义函数时,您必须在相等的谓词中将它们的返回值与值 1 进行比较。在同一 LDAP 昵称中,您还必须与应用列的任何其他谓词一起使用 AND,如清单 24 所示。

清单 24. 适用于 LDAP 搜索配置参数的正确自定义函数示例
SELECT * FROM ldap_nickname 
   WHERE ldap.search_scope(ldap_nickname.column, ‘ONELEVEL’)=1 
   AND location='CA';

SELECT * FROM ldap_nickname1,ldap_nickname2 
   WHERE ldap.search_dn(ldap_nickname1.column,'cn=dn1')=1 
   AND     ldap.search_dn(ldap_nickname2.column,'cn=dn2')=1;

清单 25 显示了不正确的语句,其将返回错误信息 SQL0142N(SQL 语句不支持)

清单 25. 适用于 LDAP 搜索配置参数的不正确自定义函数示例
SELECT * from ldap_nickname 
   WHERE ldap.search_scope(ldap_nickname.column, ‘ONELEVEL’)=1 
   OR location=’CA’;

LDAP 搜索筛选器的自定义函数

联合环境使用联合数据库服务器和 LDAP 包装器的 LDAP 目录数据源服务器查询引擎。您可以使用以下 LDAP 自定义函数来指定将谓词下推到 LDAP 目录数据源服务器:

  • ldap.eq
  • ldap.ge
  • ldap.le
  • ldap.gt
  • ldap.lt

在自定义函数中,您必须输入搜索条件列参数和查询条件参数。以下的示例显示了 ldap.eq 语句: ldap.eq (<search term column>,<query term>)

在您设置搜索条件列参数值时,您必须引用在 LDAP 昵称中定义的列。查询条件参数值必须是文字的,或者是一个主机变量。您不能使用算术或字符串连接。即便您定义了搜索条件列允许空值,查询条件参数值也不能是 NULL。即便您通过不同数据类型定义了搜索条件列,Varchar 也是查询条件参数的有效数据类型和格式。

函数返回整数结果,当函数用于谓词中时,必须通过使用 = 或者 <> 运算符将返回值与值 1 进行比较。例如,清单 26 显示了如何使用自定义函数。

清单 26. 为 LDAP 搜索筛选器使用自定义函数的示例
SELECT * FROM department WHERE ldap.eq (name, ’development’) = 1;

SELECT * FROM department WHERE ldap.eq (name, ’development’) <> 1;

表达式 NOT (ldap.eq (col,value) = 1) 等同于 ldap.eq (col,value) <> 1

因为这些运算符的语义在 LDAP 目录数据源服务器和联合数据服务器之间并不是完全相同的,所以昵称列上的关系谓词(如 =LIKE<>)将不下推到 LDAP 目录数据源服务器进行处理。因为关系谓词可通过联合数据库服务器补偿,所以如果您将关系谓词和 LDAP 自定义函数谓词混合到一起,则您将接收到错误消息 SQL0142N(SQL 语句不支持)。例如,清单 27 显示了一个查询,其不正确地分隔了通过包装器 (ldap.eq) 处理的谓词部分和联合数据库服务器必须处理的员工的关系谓词。

清单 27. LDAP 搜索筛选器的自定义函数的不正确示例
SELECT * FROM department  WHERE ldap.eq (name, ’mark*’) = 1 OR employees>3;

所有自定义函数都被转换为 LDAP 搜索筛选器。例如,清单 28 显示了如何通过自定义函数定义昵称。

清单 28. 用于说明 LDAP 搜索筛选器的自定义函数使用的昵称
CREATE NICKNAME Department (
   department VARCHAR(20) NOT NULL, 
   name VARCHAR (150),
   employees INTEGER,
   country VARCHAR(50),
   location VARCHAR(10)) 
   FOR SERVER ldap_server 
   OPTIONS (
     DN 'ou=IBM'
     OBJECTCLASS 'department');

表 7 显示了如何通过 LDAP 包装器将 SQL 查询转换为 LDAP 搜索筛选器。

表 7. 示例显示了 SQL 查询转换为 LDAP 搜索筛选器
描述SQL已转换的 LDAP 查询筛选器
无谓词查询SELECT * FROM Department(objectclass=department)
带有关系谓词的查询SELECT * FROM Department where location='CA'(objectclass=department)
查询谓词中的 ldap.eqSELECT * FROM Department WHERE ldap.eq(location, 'NY')=1(&((location=NY)(objectclass=department))
查询谓词中的 ldap.eqSELECT * FROM Department WHERE ldap.eq(name,'Mark*')=1(&(name=Mark*)(objectClass=department))
查询谓词中的 ldap.geSELECT * FROM Department WHERE ldap.ge(employees ,'20')=1(& (employees>=20)(objectClass=department))
查询谓词中的 ldap.leSELECT * FROM Department WHERE ldap.le(employees ,'20')=1(& (employees<=20)(objectClass=department))
查询谓词中的 ldap.gtSELECT * FROM Department WHERE ldap.gt(employees,’40’)=1(&(&(employees>=40)(!(employees=40)))(objectClass=department))
查询谓词中的 ldap.ltSELECT * FROM Department WHERE ldap.lt(employees,’40’)=1(&(&(employees<=40)(!(employees=40)))(objectClass=department))
查询谓词中的 ANDSELECT * FROM Department WHERE ldap.eq(location,'CA')=1 AND ldap.le(employees,’20’)=1(&(&(location=CA)(employees<=20))(objectClass=department))
查询谓词中的 ORSELECT * FROM Department WHERE ldap.eq(location,'CA' )=1 OR ldap.eq(location , 'NY)'=1;(&(|(location=CA)(location=NY))(objectClass=department))
查询谓词中的 NOTSELECT * FROM Department WHERE NOT ldap.eq(location,'CA')=1
SELECT * FROM Department WHERE ldap.eq(location,'CA')<>1
(&(!(location=CA))(objectClass=department))

如何通过多值属性查询 LDAP 条目

虽然在关系模型中字段不能具有多个值,但是在 LDAP 条目中的属性可以有多个值。以下示例解释了针对 LDAP 昵称的查询如何在多值 LDAP 属性情况下进行。

假设您具有多值 LDAP 条目,如:

清单 29. 多值 LDAP 条目的示例
   dn: value=1,dc=example       
   objectClass: data
   value: 1
   value: 2

清单 30 将昵称定义为 nick_char,且定义有 column 字符串类型和 DELIMETER 列选项。

清单 30. 定义昵称 nick_char
   CREATE NICKNAME nick_char (value  VARCHAR(256) OPTIONS (DELIMETER ';')) 
      FOR SERVER …
      OPTIONS(…);

清单 31 显示了如何通过不使用 DELIMETER 的非字符串类型列来定义 nick_int

清单 31. 定义昵称 nick_int
CREATE NICKNAME nick_int (value  integer) 
   FOR SERVER …
   OPTIONS(…);

将查询与关系谓词配合使用时,通过联合数据库服务器补偿谓词。对于使用关系谓词的多值列来说,虽然检索了所有的 LDAP 条目数据,但是只有第一个值被返回到联合数据库进行处理。

清单 32 显示了查询如何检索条目并只显示第一个值。

清单 32. 通过关系谓词查询昵称 nick_char 和 nick_int
SELECT * FROM nick_char WHERE value=’1;

SELECT * FROM nick_int WHERE value=1;


VALUE
---------------
1

清单 33 显示了无法检索条目的查询。

清单 33. 通过关系谓词查询昵称 nick_char 和 nick_int
SELECT * FROM nick_char WHERE value='2’;

SELECT * FROM nick_int WHERE value=2;

在谓词中您可以使用 LDAP 搜索筛选器的自定义函数以便使 LDAP 目录服务器处理搜索筛选器。LDAP 目录服务器的规则说明如果 LDAP 条目具有包括值匹配的 ANY 的属性,则将检索标准。

清单 34 显示了查询昵称如何为 nick_char 使用 ldap.eq 以便检索示例条目并显示所有的值。

清单 34. 通过自定义函数查询昵称 nick_char 和 nick_int
SELECT * FROM nick_char WHERE ldap.eq (‘value’, ‘1’) = 1;

SELECT * FROM nick_char WHERE ldap.eq (‘value’, ‘2’) = 1;

VALUE
---------------
1;2

清单 35 显示了如何为 nick_int 使用 ldap.eq 以便检索只显示第一个值的示例条目。LDAP 包装器只将第一段数据从 string 转换为 integer,然后将其返回到联合数据库服务器。

清单 35. 通过自定义函数查询昵称 nick_char 和 nick_int
SELECT * FROM nick_int WHERE ldap.eq (value, ‘1’) = 1;

SELECT * FROM nick_int WHERE ldqp.eq (value, ‘2’) = 1;

VALUE
---------------
1

如何优化 LDAP 包装器性能

您可以优化 LDAP 包装器性能来最小化在 LDAP 目录数据源服务器和联合服务器之间传送的数据数量。

联合环境中的 LDAP 包装器使用联合数据库和 LDAP 目录数据源服务器查询引擎。联合数据库引擎处理在昵称列中指定的谓词(关系运算符如 =BETWEENLIKE<>)。LDAP 目录数据源服务器引擎处理使用搜索筛选器的 LDAP 自定义函数的谓词。

通过结构化您的查询以在任何可能时候将数据处理下推到 LDAP 系统,您可以最小化在两个搜索引擎之间传送的数据数量。


将 LDAP 目录数据与其他企业数据源联接

现在您已经配置了 InfoSphere Federation Server 来访问 LDAP 目录数据,所以可以将此数据与来自其他数据源的数据进行联接和统一。

在您的环境中,您可以为其他数据源添加适当的包装器、服务器、用户映射和昵称对象。此过程类似于配置 InfoSphere Federation Server 以便服务 LDAP 目录数据源服务器,虽然对于不同数据源会有所不同。要获得更多信息,请参考 InfoSphere Federation Server 文档、教程或红皮书。

本节说明如何发出示例查询,以将 LDAP 条目中的数据与联合数据库中预定义的昵称中的数据联接。

清单 36 显示了 EMPLOYEE 的结构,其是 InfoSphere Federation Server 上的预定义昵称。

清单 36. 昵称 EMPLOYEE 的结构
EMPLOYEE
	empno (primary key, char(6))
	firstname (varchar(12))
	midiint (char(1))
	lastname (varchar(15))
	workdept (char(3))
	photo (char(4))
	hiredate (date)
	job (char(8))
	  ...

清单 37 显示了 DEPARTMENT 的结构,您已经为其定义了 LDAP 昵称。

清单 37. 昵称 DEPARTMENT 的结构
DEPARTMENT
   department (varchar(20))
   name (varchar (150)
   employee(integer)
   country COUNTRY (varchar(50))
   location (varchar(10))

清单 38 显示了您可以写入的 SELECT 语句以便列出员工信息,其部门位置是 CA

清单 38. 联接昵称 EMPLOYEEDEPARTMENT
SELECT empno,firstname,lastname,workdapt, job
   FROM DEPARTMENT D, EMPLOYEE E
   WHERE D.department= E.workdept
   AND ldap.eq(D.location, ‘CA’)=1;

您可以直接从命令窗口、控制中心的可用工具或第三方产品的可用工具发布此联接查询。如果您不愿意编写您自己的 SQL 语句,您可以使用控制中心或第三方工具来以图形方式构造您的联接查询。


结束语

此教程向您显示了如何部署并配置 LDAP 包装器,包括如何创建 LDAP 包装器、服务器、用户映射和昵称对象。具体的示例向您显示了如何查询 LDAP 数据源。本教程还提供了 LDAP 包装器的性能技巧。最后,一个简单的示例演示了如何将 LDAP 昵称与其他昵称联接。


下载

描述名字大小
本文使用的 LDAP WrapperLDAPWrapper.zip34KB

参考资料

学习

获得产品和技术

  • 下载 IBM 产品评估版,试用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management, Tivoli, Java technology
ArticleID=606698
ArticleTitle=通过 InfoSphere Federation Server 使用 LDAP 包装器
publish-date=01062011