Обновление: прежде чем читать дальше!
Тогда это не было проблемой с кодом —
оба веб-сервера не были подключены к одной базе данных, поэтому я был
запрашивающий нулевого пользователя (мне сказали, что это тот же самый БД и верил там
должен быть пользователь с id = 5).
Я новичок в php и веб-серверах, поэтому я не продвинутый пользователь. Я в настоящее время разрабатываю мыльный клиент. Для этой цели наша компания создала два веб-сервера — они абсолютно одинаковые, однако для одного требуется проверка подлинности 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";
}
?>
Работает отлично. Имея схожие функции (другие имеют больше параметров, но код такой же), все было замечательно, пока я не попытался сделать то же самое с клиентом, защищенным паролем.
Мой код с проверкой подлинности 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. Может быть, защищенный паролем веб-сервер не может подключиться к БД (но тогда он не получит параметры?)
3.Может быть, есть еще какие-то детали аутентификации, о которых я не знаю, но я должен был их включить, и поэтому моему клиенту не разрешено читать ответ?
Другая информация, которая может быть релевантной: Я использую PHP 7.0.4., IIS 7.5., И все настройки, связанные с Mapping и Auth, включены. Кроме того, существует партнер с id = 5, и я проверил для функции все до 20, но они все показывают как нулевые в коде, даже если это не так. Любая реализованная функция, которая работала с клиентом без пароля, возвращает нуль с паролем, защищенным паролем.
Я буду очень признателен за любую помощь и даже идеи. Я застрял здесь на неделю с этим проектом в целом, но не нашел ни одной подобной проблемы, опубликованной кем-либо еще.
Задача ещё не решена.
Других решений пока нет …