具有ntlm身份验证的php soap客户端返回null(但在没有auth的情况下适用于1:1客户端)

时间:2016-04-05 08:46:41

标签: php authentication soap client ntlm

  

更新:在您进一步阅读之前!
  那时代码不是问题 -   两个web服务器都没有连接到同一个数据库,因此我是   请求一个空用户(我被告知它是相同的数据库,并相信那里   应该是id = 5的用户。

我是php和web服务器的新手,所以我不是高级用户。我目前正在开发一个肥皂客户端。为此,我们公司制作了两个网络服务器 - 它们完全相同,但是,一个需要NTLM身份验证,但另一个需要免费访问(由于客户端数据我不提供链接)。

我的PHP代码我曾经在没有密码的情况下从网络服务器调用一个函数:

<?php
header('Content-Type:text/plain');
try{
    $client = new SoapClient("http://sensitive/sensitive/ws/nopass.svc?wsdl" );
    $params = array(
        'id' => "5" 
    );
    print_r($client->GetPartnerById( $params ));
}
catch (Exception $e) {
    echo 'Caught exception:',  $e->getMessage(), "\n";
}
?>

完美无缺。有类似的功能(其他人有更多的参数,但代码是相同的),eveything很棒,直到我尝试用密码保护客户端做同样的事情。

我的代码使用NTLM身份验证:

<?php
header('Content-Type:text/plain');

// modification of Rabaix code @ https://thomas.rabaix.net/blog/2008/03/using-soap-php-with-ntlm-authentication

class NTLMStream {
    private $path; private $mode; private $opened_path; private $buffer; private $pos;
    public function stream_open($path, $mode, $opened_path) {
        $this->path = $path;
        $this->mode = $mode;
        $this->opened_path = $opened_path;
        $this->createBuffer($path);
        return true;
    }
        public function stream_close() {
        curl_close($this->ch);
    }
    public function stream_read($count) {
        if(strlen($this->buffer) == 0) {return false;}
        $read = substr($this->buffer,$this->pos, $count);
        $this->pos += $count;
        return $read;
    }
    public function stream_write($data) {
        if(strlen($this->buffer) == 0) {return false;}
        return true;
    }
    public function stream_eof() {
        if($this->pos > strlen($this->buffer)) {return true;}
        return false;
    }
    public function stream_tell() {
        return $this->pos;
    }
    public function stream_flush() {
        $this->buffer = null;
        $this->pos = null;
    }
    public function stream_stat() {
        $this->createBuffer($this->path);
        $stat = array('size' => strlen($this->buffer));
        return $stat;
    }
    public function url_stat($path, $flags) {
        $this->createBuffer($path);
        $stat = array('size' => strlen($this->buffer));
        return $stat;
    }
    private function createBuffer($path) {
        if($this->buffer) {return;}
        $this->ch = curl_init($path);
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
        curl_setopt($this->ch, CURLOPT_USERPWD, $this->user.':'.$this->password);
        $this->buffer = curl_exec($this->ch);
        $this->pos = 0;
}   }
class NTLMSoapClient extends SoapClient {
    protected $validate = false;
    function __doRequest($request, $location, $action, $version, $one_way=0) {
        $headers=array('Method: POST','Connection: Keep-Alive','User-Agent: PHP-SOAP-CURL','Content-Type: text/xml; charset=utf-8','SOAPAction: "'.$action.'"');
        $this->__last_request_headers = $headers;
        $ch = curl_init($location);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POST, true );
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
        curl_setopt($ch, CURLOPT_USERPWD, $this->user.':'.$this->password);
        $response = curl_exec($ch);
        return $response;
    }
    function __getLastRequestHeaders() {
    return implode("\n", $this->__last_request_headers)."\n";
}   }
class MyServiceProviderNTLMStream extends NTLMStream {
    protected $user = 'myusername';
    protected $password = 'password123';
}
class MyServiceNTLMSoapClient extends NTLMSoapClient { 
    protected $user = 'myusername';
    protected $password = 'password123';
}

// code begins here
$url = 'http://services.domain.lv/sensitive/sensitive/yespass.svc?wsdl';
stream_wrapper_unregister('http');
stream_wrapper_register('http', 'MyServiceProviderNTLMStream') or die("Failed to register protocol");

$client = new MyServiceNTLMSoapClient($url);

try{
    $params = array('id' => "5");
    print_r($client->GetPartnerById( $params)); //prints blank values
    var_dump($client->GetPartnerById($params)); //prints null values
    // echo json_encode($client->GetPartnerById( $params )); isn't helping either
catch (Exception $e) {
    echo 'Caught exception:',  $e->getMessage(), "\n";
}

stream_wrapper_restore('http');
?>

我得到的var_dump部分

的回复
object(stdClass)#1 (1) {
  ["GetPartnerByIdResult"]=>
  object(stdClass)#3 (18) {
    ["Code"]=> NULL
    ["CompanyName"]=> NULL
    ["Email"]=> NULL
    ["FirstName"]=> NULL
    ["IsClient"]=> NULL
    ["IsCompany"]=> NULL
    ["IsSupplier"]=> NULL
    ["LastName"]=> NULL
    ["LastUpdateTime"]=> NULL
    ["LastUpdateUser"]=> NULL
    ["NotUsed"]=> NULL
    ["Notes"]=> NULL
    ["ParentCompanyId"]=> NULL
    ["PartnerId"]=> int(0)
    ["Phone"]=> NULL
    ["RegistrationCode"]=> NULL
    ["VatCode"]=> NULL
    ["Webpage"]=> NULL
  }
}

我有不同的理论:

1.这可能与我的本地网络上有一个网络服务器有关,但受密码保护的网络服务器是在线的;

2.可能受密码保护的Web服务器无法连接到DB(但它不会获取参数,不是吗?)

3.也许还有一些我不知道的身份验证细节,但我必须加入,因此我的客户不允许阅读回复?

其他可能相关的信息:我使用的是PHP 7.0.4。,IIS 7.5。,并且启用了所有与地图和身份验证相关的设置。此外,存在一个id = 5的伙伴,我已经检查了函数all直到20,但它们都在代码中显示为null,即使它们不是。任何与无密码客户端一起使用的已实现函数,都会返回带密码保护的函数。

我将非常感谢任何帮助,甚至是想法。我整个这个项目都被困在这里一个星期,但没有发现其他人发布的类似问题。

0 个答案:

没有答案