IT星球论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 459|回复: 0

使用SoapHeader实现Soap请求验证

[复制链接]

2004

主题

1

好友

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

优秀会员 助人为乐 辛勤工作 技术精英 多才多艺 优秀班竹 灌水天才 星球管理 宣传大使 灌水之王 财富勋章 版主勋章 动漫勋章 勤奋会员 论坛精英 PS高手 心 8 闪游皮肤 双鱼座 8★8➹ 志愿者 乖

发表于 2015-12-2 12:57:45 |显示全部楼层
使用SoapHeader实现Soap请求验证
PHP的Soap Extension中, 对于SoapServer来说, 并没有方法可用得到/处理客户端发送的SoapHeader信息.
网上也有很多人认为, 只能通过读取PosT过来的请求XML文件, 分析, 才能得到客户端发送过来的SoapHeader.
但, 其实在SoapServer端, 其实是有一种办法, 可用把SoapHeader当作一个请求来处理, 从而获取到客户端提交的SoapHeader信息.
假设客户端代码如下:
  1.     <?php
  2.     /*
  3.     * 保存用户名和密码的载体
  4.     */
  5.     class SoapUserInfo {
  6.         /**
  7.           * @var char $name
  8.           */
  9.         public $name;
  10.         /**
  11.           * @var char $password
  12.           */
  13.         public $password;
  14.      
  15.         public function __construct($l, $p) {
  16.             $this->Password = $p;
  17.             $this->Username = $l;
  18.         }
  19.     }
复制代码
然后客户端生成SoapHeader
  1.     <?php
  2.         $soap_header = new SoapHeader("http://www.laruence.com", 'Authorise'
  3.                    , new SoapUserInfo('laruence', 'password'), false, SOAP_ACTOR_NEXT);
复制代码
也许细心的同学会注意到第4个参数FALSE第5个参数SOAP_ACTOR_NEXT, 这是什么呢? 我最后再讲.
然后, 创建客户端, 绑定SoapHeader
  1.     <?php
  2.         $client = new SoapClient($wsdl);
  3.         $client->__setSoapHeaders(array($soap_header));
  4.         $client->__soapCall('request', array());
复制代码
现在, 客户端已经发起了请求, 请求中也包含了SoapHeader, 其中有了我们验证需要的用户名/密码信息.
那么, 在服务端, 该如何做呢?
  1.     <?php
  2.     $server = new SoapServer('laruence.wsdl');
  3.     $server->setClass('InterfaceClass');
  4.     $server->handle();
复制代码
关键的地方就在, 服务端接收请求以后, 会实例化一个处理类, 然后分析SoapHeader, 接着就会调用InterfaceClass::Authorise这个方法(Authorise是我们请求头中的变量名), 所以, 我们就可用在InterfaceClass类中, 定义个Authorise方法, 并在这个方法中对SoapHeader中的信息做验证.
然后, 请求体(Soap body)中的方法被调用, 因为不论Authorise方法返回什么(除非exit), 请求体中的方法一定会被调用, 所以要寻找个变量记录验证的结果.
  1.     <?php
  2.     class InterfaceClass {
  3.          /**
  4.           * @var bool $authorized
  5.     */
  6.         private $authorized = FALSE;
  7.         /*
  8.     * Authentication function
  9.     *
  10.     * @param string username
  11.     * @param string password
  12.     */
  13.         public function Authentication($username, $password) {
  14.               $this->authorized = validateUser($username, $password);
  15.         }
  16.      
  17.         /*
  18.     * Test method
  19.     */
  20.         public function request(){
  21.               if ($this->authorized) {
  22.                    //验证成功, 继续处理.
  23.               } else {
  24.                    //验证失败, 拒绝请求.
  25.               }
  26.         }
  27.     }
复制代码
当然, 对于网上说的另外一种方法, 通过分析请求的XML文件, 也可以:
  1.     <?php
  2.     class InterfaceClass {
  3.          /**
  4.           * @var bool $authorized
  5.     */
  6.         private $authorized = FALSE;
  7.         function __construct() {
  8.              $xml = file_get_contents('php://input');
  9.              //分析xml, 获得SoapHeader数据, 验证
  10.         }
  11.     }
复制代码
Must Understand这个参数指明了, 是否服务端必须要了解SoapHeader, 如果这个参数为真, 而服务端并不能识别响应的Header, 则会引发一个Soap Fault(Header not understood).
SOAP_ACTOR_NEXTactor指明了SoapHeader要传递给谁, 被谁处理.
SOAP_ACTOR_NEXT的意思就是, 下一个接受到这个请求头的Service, 在本文的例子中只有一个Server,当然也就没有关系了.
在SoapServer的构造函数中, 我们可以指明一个Server的Actor, 比如:
  1.     <?php
  2.     $server = new SoapServer($wsdl, array('actor' => 'laruence'));
复制代码
这样, 我们就可以在Client的SoapHeader中, 通过设置actor是laruence, 来让指定的Server来获得我们设置的头部的信息.








使用SoapHeader实现Soap请求验证

该会员没有填写今日想说内容.
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

回顶部