Delphi实现WebService带身份认证的数据传输

Delphi实现WebService带身份认证的数据传输


  WebService
使得不同开发工具开发出来的程序可以在网络连通的环境下相互通信,它最大的特点就是标准化(基于XML的一系列标准)带来的跨平台、跨开发工具的通用性,基于HTTP带来的畅通无阻的能力(跨越防火墙)。
  WebService 给我们的软件开发带来了诸多好处,但是有一点还是必须要考虑到的,那就是安全问题。提供Service的一方要控制用户的限制访问,就要对来访的用户进行   身份验证。验证成功则继续提供服务,否则就触发无权访问的异常,返回给客户。那么现在我们要解决的问题是这样的:用户的身份认证信息如何在调用主要服务前 发送到服务方,从而进行验证?
  在WebService中,用户身份认证信息可以在客户端通过soap头(soap header)进行传送。在 WebService服务端的编写中,需要对soap头进行处理,这个处理过程就是提取Soap Header中的用户认证信息进行验证。下面就来看看在 Delphi中这个身份认证是如何实现的。
 
  一、   自定义的Header类
  你需要定义一个用来存放认证信息的类,这个类继承于TSoapHeader。
  TAuthHeader = class(TSOAPHeader)
  private
  FUserName: WideString;
  FPassWord: WideString;
  published
  property UserName: WideString read FUserName write FUserName;
  property PassWord: WideString read FPassWord write FPassWord;
  end;
  这个类包含了用户名和密码两个属性,当然你可以根据情况增加更多的信息。
  再说一下这个类是在哪定义的,它是定义在服务端的接口声明单元。服务发布以后,生成的WSDL中会有这个类的定义,这样在客户端用WSDL Importer导入接口单元的时候,这个类也会自动生成,当然你还要在服务端对这个类进行注册:
  InvRegistry.RegisterHeaderClass(TypeInfo(ISoapAuth), TAuthHeader);
  RemClassRegistry.RegisterXSClass(TAuthHeader);
  ISoapAuth是服务端提供的服务接口。
 
  二、   客户端发送Header
  我们还假设ISoapAuth是服务端提供的服务接口,它提供了GetInfo()这么一个服务。
  客户端程序片段:
  procedure TClientForm.GetInfoButtonClick(Sender: TObject);
  var
  aIntf: ISoapAuth;
  Headers: ISOAPHeaders;
  H: TAuthHeader;
  Begin
  aIntf := (HTTPRio as ISoapAuth);
  H := TAuthHeader.Create;
  H.UserName := ‘piao’ ; //这里只是举个例子
  H.PassWord := ‘840717’; 
  Try
  Headers := (aIntf as ISOAPHeaders);
  Headers.Send(H); //发送Soap Header
  aIntf.GetInfo; //调用服务
  finally
  aIntf := nil;
  H.Free;
  End;
  end;
  客户端的工作就是这些了,能否调用服务还要看服务端的处理结果了。
 
  三、   服务端接收处理Header
  服务端程序片段:
  function TSoapAuth.GetServerInfo: WideString;
  var
  Headers: ISoapHeaders;
  H: TAuthHeader;
  begin
  Headers := Self as ISoapHeaders;
  Headers.Get(TAuthHeader, TSoapHeader(H)); //先获取SoapHeader
  try
      if H = nil then //SoapHeader 为空
        raise ERemotableException.Create('No authentication header')
      else
        if not CheckUser(H.UserName, H.PassWord) then   //验证失败
          raise ERemotableException.Create('No acess to call on service!');
  finally
      H.Free;
  end;
  Result := 'Hello World!';
  end;
  以上,TSoapAuth是继承于TInvokableClass 实现 ISoapAuth 的类。
  CheckUser()是用来验证用户是否具有访问权限的函数,在服务端定义。
  这只是个简单的返回字符串的服务。
 
 
  四、   对访问WebService的用户的状态的探讨
  事 实上客户端在每次调用服务端的服务接口时会重新生成一个对象,发送请求,然后接收返回结果,整个调用过程结束后这个对象就被释放。所以可以说 WebService是个无状态的对象,也就不存在用户是否登陆的说法。这样的结果使得我们每次调用服务时就必须做一次用户认证(这个认证可能是查询数据   库比对),是比较浪费时间和资源的。
  如果一定要在服务端保存用户的登陆状态,那么可以在服务端加一个LogIn()的函数。当用户第一次访问服务   时,调用LogIn()记录下用户的状态信息,并且赋给这个用户在一段时间内无限制(是指不必经过CheckUser这个过程)访问服务的权限,当这段时 间过后,用户的登陆状态被释放掉,必须重新登陆才能继续调用服务。
  至于这个用户状态信息如何在服务端保存,就可能有几种方法了。一是用文件形式保存(xml或ini),二是数据库保存,三是用程序中的变量保存(可以在程序中定义一个UserList的变量来记录用户的状态信息)。

 


转载于:https://my.oschina.net/u/582827/blog/348404

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值