I have wsld url. I have to add custom http request header to authorize for this wsdl. When I try soapclient as following , I get error.
/* userName and password is masked in this question */
$opts = array(
'http'=>array(
"userName:xxxxx\r\n".
"password:xxxxxx\r\n"
)
);
$streamContext = stream_context_create($opts);
$cilent = new SoapClient("https://iflyrestest.ibsgen.com:6013/iRes_Booking_WS/services/AvailabilityPort?wsdl" , array('stream_context' => $streamContext));
Error:
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't find <definitions> in
Because response is like 'You are not authorized to access this URL...'
Also When I try function 'file_get_content()' with same stream_context, I successfully get content of this url.
How should I use soapclient for this case ?
if you're sure it is a basic authentication, then you can simply use the login and password SoapClient options, instead of stream_context, with your credentials, it should work then.
Related
I'm currently developing a payment gateway that has to send the order to Navision where it will be managed. In the webservice the NTML authentication is enabled so first it is necessary to extend the native class SoapClient. For it I have found enough documentation in the web https://thomas.rabaix.net/articles/using-soap-php-with-ntlm-authentication that allows to extend this native class.
Now the code exposed in that post does not return me the xslm first.
In this case this would be my code
define("USERPWD", "user:password");
require_once("NTLMStream.php");
require_once("NTLMSoapClient.php");
stream_wrapper_unregister('http');
stream_wrapper_register('http', 'NTLMStream') or die("Failed to register protocol");
// Initialize Soap Client
$url = "http://ipaddress:port/DynamicsNAV1_test/WS/enterprise/Codeunit/SalesEnterprise?WSDL";
$uri = "urn:microsoft-dynamics-schemas/codeunit/SalesEnterprise";
$params = [
'stream_context' => stream_context_create([
'ssl' => [
'verify_peer'=>false,
'verify_peer_name'=>false,
'allow_self_signed'=>true,
]]),
'cache_wsdl'=> WSDL_CACHE_NONE,
'trace' => 1,
];
$client = new NTLMSoapClient($url, $params);
stream_wrapper_restore('http');
As you can see I have dispensed with the classes used by this author to define the credentials.
inally the code returns the following error:
SOAP Fault: (faultcode: WSDL, faultstring: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://ipaddress:port/DynamicsNAV1_test/WS/Enterprise/Codeunit/SalesEnterprise?WSDL' : Document is empty).
I will be happy to provide more information if needed. Many thanks in advance!
The first 2 responses you get from an NTLM handshake are 401's with no body, the 3rd response if successfully authenticated will contain the 200 and response.
https://techcommunity.microsoft.com/t5/iis-support-blog/windows-authentication-http-request-flow-in-iis/ba-p/324645
Update 30/1/21
Its been a while since ive used Php, but id start with this post that shows how to manually do the NTLM curl from the shell then how to repeat that same command from php curl - curl with ntlm authentication works in command line but not inside php
Also there are some nuggets in the top few answers of this SO search: https://stackoverflow.com/search?q=NTLM+PHP+curl
I had this issue with the same SOAP exception, but the code similar to yours was working fine with NAV2013. The company I'm working for upgraded to NAV2020 and then the SOAP Exception appeared. After countless hours of back and forward of refactoring, and researching the web, the solution is on the Microsoft documentation... The issue is that in the original code for NTLMSoapClient class you have to change the following line:
'Content-Type: text/xml; charset=UTF-8'
Which is under the variable $headers in the method processRequest to:
'Content-Type: text/xml; charset=ISO-8859-1'
At some point Dynamics API is no longer accepting credentials with Unicode characters. I hope this works for you as it did for me.
Here is my request in SoapUI:
With SoapUI i send the request and i receive good response.
Here is my PHP code so far:
<?PHP
$wsdl = 'https://onlinefatura.xyz/foyws/FoyOnlineApiGateWS.asmx';
try{
$clinet=new SoapClient($wsdl);
$ver =array(
"UserName"=>"USERNAME",
"Password"=>"PASSWORD",
"ApiKey"=>"APIKEYHERE",
"Date"=>"2017-11-09",
);
$quates=$clinet->GetAddedBalanceList($ver);
var_dump($quates);
}
catch(SoapFault $e)
{
echo $e->getMessage();
}
When i execute the code i receive:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://onlinefatura.xyz/foyws/FoyOnlineApiGateWS.asmx' : Premature end of data in tag html line 3
Somehow i'm doing something wrong. I'm not really sure if i made my PHP request correct.
Where is my mistake, and how the correct request should look like ?
With an SoapClient error like "Premature end of data in tag html" your link to the WSDL file is usually not correct.
Try this one: https://onlinefatura.xyz/foyws/FoyOnlineApiGateWS.asmx?WSDL
I'm trying to consume a SOAP webservice from a distant server, the wsdl file is located here http://ecolinthcm.pi-asp.de/logaserver/services/UsersService?wsdl
I've been in touch with the developers there but they keep telling me that it works fine so they're not of great help...
I'm using this little piece of code to poke the bear see if it's alive :
$WSDL = "http://ecolinthcm.pi-asp.de/logaserver/services/UsersService?wsdl";
// the file_get_contents methods doesn't change the end result unfortunately
//$data = file_get_contents($WSDL);
//file_put_contents('./wsdl.xml',$data);
//$WSDL = './wsdl.xml';
$opts = array(
'http'=>array(
'user_agent' => 'PHPSoapClient'
)
);
$context = stream_context_create($opts);
$service = new SoapClient($WSDL,array('stream_context' => $context, 'cache_wsdl' => WSDL_CACHE_NONE));
$result = $service->ErmUserBean (array("UserID","Password","TargetUserID"));
print '<pre>';
var_dump($result);
print '</pre>';
As said in the title I get this message in return :
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't find < definitions > in 'WSDL file URI' in C:\Users\username\Documents\EasyPHP-DevServer-14.1VC11\data\localweb\projects\API\index.php:30 Stack trace: #0 C:\Users\username\Documents\EasyPHP-DevServer-14.1VC11\data\localweb\projects\API\index.php(30): SoapClient->SoapClient('WSDL file URI', Array) #1 {main} thrown in C:\Users\username\Documents\EasyPHP-DevServer-14.1VC11\data\localweb\projects\API\index.php on line 30
I've read most post about this errors and therefore tried a lot of variation in my SOAP request. I've also edited my php.ini file so that the line
extension=php_openssl.dll
appears without ";" (comment) before as I could read here.
The error message you get is correct because the WSDL you linked to is invalid. You can download it and feed it to a WSDL validator (e.g. https://www.wsdl-analyzer.com/) and you will see it is invalid and fails with a similar validation message.
The WSDL is invalid because certain namespaces are wrong. For example, the namespace for the WSDL schema is not https://schemas.xmlsoap.org/wsdl/ and neither is https://www.w3.org/2001/XMLSchema the namespace for XML schema. The correct ones are with http:// not https://.
I fixed the namespaces and uploaded a valid WSDL file here: http://filebin.ca/2lByBlPAOvCu/ChangedUsersService.xml. You can compare it with the original file which I saved here: http://filebin.ca/2lBxfIDsyDas/OriginalUsersService.xml and see the differences.
Try using my WSDL file. Feed it to the online validator and to your code and see if it works.
I try to create script for communication with WS-Security (for the first time) in PHP:
require ('WSSoapClient.php');
$soapclient = new WSSoapClient('https://katastr.cuzk.cz/trial/dokumentace/ws22/wsdp/vyhledat_v22.wsdl');
$soapclient->__setUsernameToken('username', 'password');
$params = array('katastrUzemiKod'=>693936, 'kmenoveCislo'=>1385);
$response = $soapclient->__soapCall('najdiParcelu', $params);
var_dump($response);
And this script failed:
PHP Fatal error: Uncaught SoapFault exception: [wsse:InvalidSecurity]
Error on verifying message against security policy Error code:1000 in
/home/jura/bin/WSSoapClient.php:75
Is any way to see, what this script exactly sent to server and what was the response?
The problem is the $soapclient->__setUsernameToken('username', 'password') function is expecting a 3rd parameter of either 'PasswordDigest' or 'PasswordText'.
This is badly handled in the WSSoapClient class. It should really throw an exception if the passwordType argument is missing. What it tries to do is this:
// $this->generateWSSecurityHeader() returns an empty string if 3rd parameter missing.
$this->__setSoapHeaders($this->generateWSSecurityHeader());
If PHP is in strict mode like mine you would get these warnings:
PHP Warning: SoapClient::__setSoapHeaders(): Invalid SOAP header...
Warning: SoapClient::__setSoapHeaders(): Invalid SOAP header...
You need to figure out the password type and pass that as your 3rd argument in the setUsernameToken() function.
There is a web service URL which returns a country's cities details. I can access this web service URL in browser by direct Http Request using GET method
and works fine :
[Snip: I changed my actual domain name with example]
http://alpha.example.com/WSV2/StaticData.php?xml=<StaticDataRequest><Header><Code>TT4533</Code><Username>skyman211</Username><Password>ammkj43</Password></Header><Body><GetStaticData>cities</GetStaticData><ExtraParams><CountryCode>67</CountryCode></ExtraParams></Body></StaticDataRequest>
But when I try to access above URL via SoapClient :
/* Line 36 */
$cities = new SoapClient("http://alpha.example.com/WSV2/StaticData.php?xml=<StaticDataRequest><Header><Code>TT4533</Code><Username>skyman211</Username><Password>ammkj43</Password></Header><Body><GetStaticData>cities</GetStaticData><ExtraParams><CountryCode>67</CountryCode></ExtraParams></Body></StaticDataRequest>");
Gets me following error :
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL:
Couldn't find <definitions> in 'http://alpha.example.com/WSV2/StaticData.php?xml=
<StaticDataRequest><Header><Code>TT4533</Code><Username>skyman211</Username>
<Password>ammkj43</Password></Header><Body><GetStaticData>cities</GetStaticData>
<ExtraParams><CountryCode>67</CountryCode></ExtraParams></Body></StaticDataRequest>'
in /srv/www/htdocs/test/inc/client.php:36 Stack trace: #0 /srv/www/htdocs/test/
inc/client.php(36): SoapClient->SoapClient('http://alpha.ex...') #1 /srv/www/
htdocs/ortmas/index.php(6): InitData->getCities(67) #2 {main} thrown in /srv/
www/htdocs/test/inc/client.php on line 36
You must pass the URL to the WSDL, instead of the actual call itself.
Something like that for example :
$cities = new
SoapClient("http://alpha.example.com/WSV2/StaticData.wsdl");
If that url worked on your browser, you can try to do the following in PHP :
$url = "http://alpha.example.com/WSV2/StaticData.php?xml=<StaticDataRequest><Header><Code>TT4533</Code><Username>skyman211</Username><Password>ammkj43</Password></Header><Body><GetStaticData>cities</GetStaticData><ExtraParams><CountryCode>67</CountryCode></ExtraParams></Body></StaticDataRequest>";
$data = file_get_contents($url);