DB2 UDB 和 SOAP: 使用 DataSnap 的数据库 Web 服务

http://www.ibm.com/developerworks/cn/data/library/techarticles/0305swart/0305swart.html

 

 

Bob Swart, Bob Swart Training & Consultancy

2003 年 8 月 01 日

本文显示了如何使用特殊的 Login 方法向 DataSnap 应用程序添加认证;指出了这一认证与 SSL 证书相结合用于提高安全性的重要性;以及描述了如何向 Web 服务器机器部署 DataSnap 服务器应用程序。

简介

几个月前,我写了有关将 IBM DB2 ®Universal Database 用作分布式应用程序中后端数据库的两篇文章,其中把最初的 Windows 应用程序拆成了不相同的两层:瘦客户机层和数据库服务器层。 第一篇文章使用 Delphi 7 的 DataSnap 作为多层体系结构,而 第二篇文章添加了 SOAP 作为通信协议,从而最终形成了可用于 Windows(使用 Delphi 和 C++Builder ®)和 Linux(Kylix Delphi 版和 Kylix C++ 版)的解决方案。

我收到了关于这两篇文章的大量反馈,主要涉及部署问题,所以我想在这篇后续文章中解决这些问题,同时扩展 DataSnap SOAP 示例。除了讲述部署的步骤之外,我还要讨论一些登录和认证方面的细节,它们可能有助于提高 DB2 后端数据库的安全性。不过我们首先讨论后一主题。





回页首

添加少许安全性

在上两篇文章中,我展示了 DataSnap 客户机可以连接至 DataSnap 服务器并执行各种操作,如检索记录、更新记录、甚至删除记录,所有这些操作都不需要确认或认证。这适用于演示,但不适用于实际情况,所以这次将对 DataSnap 服务器和客户机添加较简单的安全性层(从而使您可以着手在这层周围构建甚至更为复杂的安全性层)。

TSQLConnection 组件是唯一直接与 DB2 数据库相连接的组件,TSQLConnection 组件已包含要连接至这个数据库所需的正确的用户名和密码,我已经用这样的方式(使用 TSQLConnection 组件)构建了 DataSnap 服务器。这意味着决不需要“在线路上”传递数据库用户名和密码,因而是安全的(除非有人“黑掉”了 Web 服务器并研究了 DataSnap 服务器的可执行文件,查找到用户名和密码特性)。您不需要在因特网上发送数据库用户名和密码,而应该在线路上发送特殊的“客户机”密码(禁用单个客户机比禁用数据库用户名/密码容易且影响也小)。

在很多地方 DataSnap 服务器都可以请求这样的认证,尤其是 TDataSetProvider 组件的 OnBefore 事件处理程序。这是一个组件,它实际上将来自服务器的数据(记录)发送给客户机,或根据从客户机接收到的信息来更新 DB2 表。您可以使用 OnBefore 事件处理程序来检查是否允许客户机请求记录或更新信息。

接着,您需要使用 OnBeforeGetRecords 和 OnBeforeApplyUpdates 事件处理程序“保护”服务器(使用前者请求记录,再使用后者修改服务器上的记录)。这两个事件处理程序都包含一个 OleVariant 类型的 OwnerData 参数。客户机应用程序可以在对应的 TClientDataSet 组件的 OnBefore 事件处理程序的参数中传递定制的“OwnerData”值。假定客户机应用程序已经允许最终用户输入用户名/密码,那么下面这段代码显示了 TClientDataSet 的 OnBeforeGetRecords 事件处理程序(客户机端):

procedure TForm1.ClientDataSet1BeforeGetRecords(Sender: TObject;
  var OwnerData: OleVariant);
begin
  OwnerData := CodeWord;
end;

在服务器端,您首先需要检查传入的 OwnerData 不为 null(即空值),随后将它指定给 WideString 并将它与具体的 CodeWord 作比较:

const
  CodeWord = 'Open Sesame';
procedure TCustomerOrders.dspCustomerBeforeGetRecords(Sender: TObject;
  var OwnerData: OleVariant);
var
  Str: WideString;
begin
  if VarIsEmpty(OwnerData) or VarIsNull(OwnerData) then Str := ''
  else Str := OwnerData;
  if Str <> CodeWord then
    raise Exception.Create('No permission to Get Records!');
end;





回页首

实现 Login 方法

实际上,您可能不单单只检查一个 CodeWord,您也许有一列实际的用户名和密码。这意味着您应该继承 DataSnap SOAP Web 服务的接口,向它添加一个 Login 方法,象下面这样:

type
  ID7DB2SAMPLE = interface(IAppServerSOAP)
    ['{E3791B81-2D4E-40C6-964E-9087AAAF35C6}']
    function Login(const UserName, Password: WideString): WideString; stdcall;
  end;

Login 方法的实现应该检查用户名和密码(例如,它们可以存储在列表、.ini 文件或其它安全数据库中),然后对正确的登录只返回 CodeWord。客户机应该保存这个 CodeWord 并在会话期间使用它:

function TD7DB2SAMPLE.Login(const UserName, Password: WideString): WideString;
begin
  if (UserName = 'Bob') and (Password = 'Swart') then
    Result := 'Open Sesame'
  else
    Result := 'Permission Denied'; // a wrong CodeWord
end;

您可以将特殊标记添加到 CodeWord 以控制其生命期或有效性 - 象客户机的 IP 地址。(这留给您作为一个练习,您可以尝试它。)

在客户机端,您现在必须从 ID7DB2SAMPLE Web 服务调用定制方法。但是 TSoapConnection 组件只公开 IAppServerSoap 方法。要使用这个附加功能,必须从已注册的 URL(本例中可能是 http://localhost/scripts/D7DB2CGI.exe/soap/ID7DB2SAMPLE )导入 Web 服务。

要导入使用 Delphi 7 的 Web 服务,可以使用 Delphi7//bin 目录下的 WSDLIMP 实用程序:

wsdlimp http://localhost/scripts/D7DB2CGI.exe/wsdl/ID7DB2SAMPLE

或者使用对象资源库(Object Repository)的 WSDL Importer(执行 File | New - Other操作并转至 WebServices选项卡):

WSDL Importer

这两种情况都会产生一个新单元 ID7DB2SAMPLE1.pas,它包含带有 Login 方法的 ID7DB2SAMPLE 的接口定义。为了使用这个接口并调用 Login 方法,您必须从 Component Palette 的 WebServices 选项卡将 THTTPRIO 组件添加到我们的客户机表单,并将其 URL 特性设置成 http://localhost/scripts/D7DB2CGI.exe/soap/ID7DB2SAMPLE

有了这个 THTTPRIO 组件,就可以连接至 Web 服务,调用 Login 方法以及保存生成的 CodeWord,这样您就可以将 CodeWord 用于随后的 OnBeforeGetRecords 和 OnBeforeApplyUpdates 事件处理程序。以下是调用 Login 的代码(源归档文件中有完整的代码):

procedure TForm1.FormCreate(Sender: TObject);
begin
  with (HTTPRIO1 as ID7DB2SAMPLE) do CodeWord := Login('Bob', 'Swart');
  cdsEMP.Active := True
end;

很显然,在我传递字符串‘Bob’和‘Swart’的位置,最终用户需要使用对话框来输入这个会话的用户名和密码(这是您可以尝试的另一个练习)。





回页首

使用 SSL 连接

在不安全的连接上发送用户名和密码不是一个好主意 - 即使只发送一次,也不是好主意,就如我在最后一个示例中做的那样。您应该始终尝试使用安全的连接来发送认证信息,幸运的是,您可以对此使用安全套接字层(Secure Sockets Layer,SSL)连接。它包含两步:第一步是在已安装 DataSnap SOAP 服务器的 Web 服务器上安装 SSL 证书(前提是如果该机器上没有 SSL 证书)。而第二步则更为简单:转到 SOAP Web 模块,选择 TWSDLHTMLPublish 组件,然后将 PublishOptions 特性的 poPublishLocationAsSecure 标志设置成 True。自此,这个 Web 服务将需要 https:// 才能够连接至该服务器(而不是 http:// ),并且加密客户机和这个服务器之间的所有信息。

与您的 Web 管理员联系,以获取有关您的 Web 服务器上 SSL 证书可用性的更多信息。

关于 Delphi 7 和 DB2 V8.1 的说明

在最近几篇文章中我一直使用 DB2 的最新版本 DB2 V8.1,我在使用过程中几乎没有碰到什么问题。但是这次,我在使用 Delphi 7 dbExpress 驱动程序和 DB2 V8.1 通用数据库个人版时遇到了一些元数据问题。尤其是,在我试着使用 BLOB 字段(诸如 EMP_PHOTO 表中的 image 字段和 EMP_RESUME 表中的 memo 字段)时,我得到了一个异常,其消息是“Could not convert variant of type (Null) into type (String)”。如果我不用这些字段,则一切都很正常。

这些问题及其它相关问题都是由于 Delphi 7、C++Builder 6 和 Kylix 3 所带的 dbExpress 驱动程序正式情况下“只”支持 DB2 V7.1 这一事实引起的,因为在发布 dbExpress 驱动程序时 DB2 的版本为 7.1。对于更新的 DB2 V8.1,dbExpress 驱动程序遇到了一些元数据不兼容性(使用 BLOB 字段),从而产生了上述结果。(请参阅 实际的报告。)

当然,Borland 已经意识到了这种情况,并正致力于开发适用于 DB2 V8.1 的更新 dbExpress 驱动程序,可望很快就可以完成。





回页首

部署 DataSnap SOAP 服务器

在论及 DataSnap SOAP 服务器的部署时,根据 Web 服务器应用程序的目标,实际上可以有几种选择(在您启动一个新的 SOAP 服务器应用程序时,您可以进行选择:请参阅 上一篇文章)。

最简单的部署是 CGI 独立可执行文件,它也是我在本文中所使用的 D7DB2SAMPLE 服务器应用程序的目标。需要将 CGI 独立可执行文件部署到 Web 服务器的(虚拟)目录中,已经对该目录的脚本编制权限进行了设置(在 Windows 上),或者已经设置了可执行文件的执行位(在 Linux 上)。

另外,在 Windows 上,您可以选择 ISAPI 动态链接库目标。CGI 可执行文件和 ISAPI DLL 之间的差别在于后者只装入一次(在第一个请求时),在您真正关闭 Web 服务器之前,它一直存在于内存中。这样做的优势在于性能:您不必为每个进入请求创建 SOAP 数据模块并连接至数据库。缺点在于缺乏灵活性:如果您想更新或更改 ISAPI DLL(例如,使用新功能),那么在可以替换 ISAPI DLL 之前,您先要关闭 Web 服务器进程(CGI 可执行文件可以被重写,但是 ISAPI DLL 将处于“使用中”状态,因此操作系统将拒绝重写它)。

您可以通过 Microsoft 的因特网信息服务(Internet Information Service,IIS)使用 ISAPI DLL,但也可以为 Windows 或 Linux 上的 Apache Web 服务器创建 Apache 共享模块(请参阅 www.apache.org,获取有关这方面的更多信息)。

最后,您可以构建的 Web App Debugger 目标专门作为调试目标,您可以在其中测试 DataSnap SOAP 服务器,而不必去真正部署它。不管哪种情况,DataSnap SOAP 服务器都必须能连接至 DB2 数据库(在我们的示例中是 SAMPLE 数据库),所以请确保在 TSQLConnection 特性中指定了正确的数据库名称、用户名和密码,并确保 DataSnap SOAP 服务器可以找到 DB2 客户机 db2cli.dll





回页首

结束语

本文中,我已经展示了如何使用特殊的 Login 方法将认证添加到 DataSnap 应用程序,该方法返回一个标识(或 CodeWord),我们必须将此标识(即 CodeWord) - 它作为 OwnerData 的一部分 - 传递给随后的 OnBeforeGetRecords 和 OnBeforeApplyUpdate 事件处理程序。我还指出了将认证与 SSL 证书相结合从而提高安全性的重要性。

最后,我略微详细地描述了在 Web 服务器机器(可以是 Windows 或 Linux)上如何部署 DataSnap 服务器应用程序。这使得在任何地方运行的瘦客户机都可以使用您的 DB2 数据库。

在以后的文章中,我将探究 Borland C#Builder IDE for .NET 上的 DB2 UDB 使用,下回见。





回页首

下载

描述文件类型文件大小下载方法
SoapClient.zipzip7 KBHTTP HTTP 下载
SoapServer.zipzip5 KBHTTP HTTP 下载

关于作者

 

Bob Swart(也称为 Dr.Bob - www.drbob42.com)在他自己的公司 Bob Swart Training & Consultancy(eBob42)(位于荷兰 Helmond)的身份是作家、教员、顾问和 Web 管理员。Bob 编写了自己的 Delphi 培训教材,并且从 1993 年以来一直在 Delphi 和 Borland 开发者大会上发表演讲。Bob 已经撰写了数百篇文章,并且还是 Revolutionary Guide to Delphi 2Delphi 4 UnleashedC++Builder 4 UnleashedC++Builder 5 Developer's GuideKylix Developer's GuideDelphi 6 Developer's Guide和即将出版的 C++Builder 6 Developer's Guide的合著者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值