PHP Soap authentication header - php

Sample Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="https://ws.intermedia.net/Account/Management">
<soapenv:Header>
<AuthentificationInfo>
<login>[PLRAdminUserName]</login>
<password>[PLRAdminPassword]</password>
<accountID>[accountID]</accountID>
</AuthentificationInfo>
</soapenv:Header>
<soapenv:Body>
<GetAccount>
<accountID>[accountID]</accountID>
</GetAccount>
</soapenv:Body>
</soapenv:Envelope>
WSDL: https://controlpanel.msoutlookonline.net/WebServices/Account/AccountService.asmx?WSDL
PHP:
ini_set("soap.wsdl_cache_enabled", "0");
$wsdl = "https://controlpanel.msoutlookonline.net/WebServices/Account/AccountService.asmx?WSDL";
$ns = 'https://ws.intermedia.net/Account/Management';
$client = new SoapClient($wsdl, array(
"trace" => 1,
"exceptions" => 0
));
$login = 'xxxx';
$password = 'xxxx';
$partnerID = 1234;
$accountID = 12345678;
$headerBody = array('AuthentificationInfo'=>array(
'login' => $login,
'password' => $password,
'accountID' => $partnerID
));
$header = new SoapHeader($ns, 'AuthentificationInfo', $headerBody);
$client->__setSoapHeaders($header);
$client->__soapCall("echoVoid", array(null));
$value = $client->GetAccount($accountID);
I'm getting the following error message:
soap:ServerServer was unable to process request. ---> Access denied; Code: 0x0008
Can anyone see anything wrong with the code?

Try with
$headerBody = array(
'login' => $login,
'password' => $password,
'accountID' => $partnerID);

just for anyone else that may ever run across this:
I changed
$ns = 'https://ws.intermedia.net/Account/Management';
to:
$ns = 'http://schemas.msoutlookonline.net';

I had an incorrect namespace.
Also Mikaƫl DELSOL's answer helped as I didn't need the array('AuthentificationInfo'=> part.
Also didn't need: $client->__soapCall("echoVoid", array(null));
Thank you!

Related

PHP Soap Fault: Could not connect to host

There are many question is similar like this. But I didn't got the solution when tried. Find my codes below:
Soap XML:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:pos="http://PostWebService.org/">
<soap:Header>
<pos:Authentication>
<!--Optional:-->
<pos:UserName>xxxxxxx</pos:UserName>
<!--Optional:-->
<pos:Password>yyyyyyyy</pos:Password>
</pos:Authentication>
</soap:Header>
<soap:Body>
.....
</soap:Body>
</soap:Envelope>
PHP Code:
$client = new SoapClient({soapurl},$params);
$auth = new stdClass();
$auth->UserName = 'xxxxxxx';
$auth->Password = 'yyyyyyyy';
$header = new SoapHeader('NAMESPACE','Authentication',$auth,false);
$client->__setSoapHeaders($header);
$result = $client->__soapCall('{soap function}',array()); // when this line executes it throws me the error "Could not connect to the host"
Please note, My Soap URL is in https. I tried lots other solutions from stack overflow but none of them work. I want anyone tell me why i am getting that error and what i did wrong in the request.
Another Code tried but still the same:
$opts = array(
'ssl' => array('ciphers'=>'RC4-SHA', 'verify_peer'=>false, 'verify_peer_name'=>false)
);
// SOAP 1.2 client
$params = array ('encoding' => 'UTF-8', 'verifypeer' => false, 'verifyhost' => false, 'soap_version' => SOAP_1_2, 'keep_alive' => false,'trace' => 1, 'exceptions' => 1, "connection_timeout" => 180, 'stream_context' => stream_context_create($opts) );
$client = new SoapClient({soapurl},$params);
//Remaining as the same above
When I tried with SoapUI it gives me a response.
Finally, I got the solution,
I found the problem. The host I was trying to connect is redirecting to another domain name. For some reason, PHP 5.6 doesn't carry the location automatically. So i defined the same soap url in the location options.
Eg:
$params = array('location' => {soapurl});
$client = new SoapClient({soapurl},$params);
Thanks for your time. :)
This solution worked for me.
E.g.
$client = new SoapClient('https://example.com/webservice.php?wsdl');
$client->__setLocation('https://www.somethirdparty.com');

SOAP working with xml via soapui but not with PHP

I am creating an SOAP client using PHP and having issues with consuming. When I test the request direct XML using soapui it responds fine and works but with PHP using SoapClient class it tells me the same credentials which I use in soapui are incorrect.
Not sure what I am missing here. My code below
Below is my XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pric="http://upshot.co.uk/pricing_request_ws">
<soapenv:Header/>
<soapenv:Body>
<pric:retrieveProductsPricing>
<username>apiuser</username>
<password>pword</password>
<postcode>EC2R 7HP</postcode>
</pric:retrieveProductsPricing>
</soapenv:Body>
</soapenv:Envelope>
Below is my PHP
$wsdl = "http://URL?wsdl";
$client = new SoapClient($wsdl, array('trace'=>1));
try
{
$options = array(
'soap_version'=>SOAP_1_2,
'exceptions'=>true,
'trace'=>1,
'cache_wsdl'=>WSDL_CACHE_NONE
);
$params = array(
'User name' => 'apiuser',
'Password' => 'pword',
'Postcode' => 'EC2R 7HP'
);
$response = $client->retrieveProductsPricing($params);
print_r($response);
}
catch(SoapFault $e)
{
print_r($e);
This is my first time configuring a soap client so I'm sure I have potentially made a mistake in this.
Have a look at the first code:
<username>apiuser</username>
<password>pword</password>
<postcode>EC2R 7HP</postcode>
You should use the same keys for the array
$params = array(
'username' => 'apiuser',
'password' => 'pword',
'postcode' => 'EC2R 7HP'
);
Useful examples

Set xml rquest header in non-wsdl soap client using php

I am trying to make a non-wsdl SOAP client call using php. My code is something like this:
try {
$URL = 'http://example.com/webservices/security/accesscontrol.asmx';
$sc = new SoapClient(null, array(
'location' => $URL,
'uri' => 'http://example.com/webservices/security/',
'trace' => 1
));
$usertoken = array('UserNameToken' =>
array(
'UserName' => 'test',
'Password' => 'test123'
));
$header = new SoapHeader('http://www.docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', 'Security', $usertoken);
$sc->__setSoapHeaders($header);
$test = $sc->__soapCall("AuthenticateClient",
array(),
array('soapaction' => 'http://example.com/webservices/security/AuthenticateClient')
);
If I debug and see the Last request header part of xml it looks like this:
<SOAP-ENV:Header>
<ns2:Security>
<item><key>UserNameToken</key><value><item><key>UserName</key><value>test</value></item><item><key>Password</key><value>test123</value></item></value></item>
</ns2:Security>
</SOAP-ENV:Header>
But if I use wsdl file, the xml header looks like this:
<SOAP-ENV:Header>
<ns2:Security>
<ns2:UserNameToken>
<ns2:UserName>test</ns2:UserName>
<ns2:Password>test123</ns2:Password>
</ns2:UserNameToken>
</ns2:Security>
</SOAP-ENV:Header>
How can I make the header part like above using non-wsdl SOAP client call? Becasue its not working and giving an error that is caused by "if either the UserName Token or the UserName was not provided in the AuthenticateClient Soap Header Request"
Thanks in advance for your help.
Please note that I have changed the URL and password intentionally as I can not disclose them.
You can create the part of the header manually and insert it into the SoapHeader, try to do something like this:
$URL = 'http://example.com/webservices/security/accesscontrol.asmx';
$soapClient = new SoapClient(null, array(
'location' => $URL,
'uri' => 'http://example.com/webservices/security/',
'trace' => 1
));
$headerPart = '
<SOAP-ENV:Header>
<ns2:Security>
<ns2:UserNameToken>
<ns2:UserName>DASKO</ns2:UserName>
<ns2:Password>welcome1</ns2:Password>
</ns2:UserNameToken>
</ns2:Security>
</SOAP-ENV:Header>
';
$soapVarHeader = new SoapVar($headerPart, XSD_ANYXML, null, null, null);
$header = new SoapHeader(
'http://www.docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', // Namespace - namespace of the WebService
'Security',
$soapVarHeader,
false // mustunderstand
);
$soapClient->__setSoapHeaders($header);

SoapClient request is not returning any data

I am trying to figure out how to use a SOAP interface.
I have managed to put together a code after exploring with soapUI.
Working soapUI request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v22="https://shop.textalk.se/webservice/v22">
<soapenv:Header/>
<soapenv:Body>
<v22:GetOrders>
<Login>
<Shop>23946</Shop>
<Username>user#mysite.com</Username>
<Password>HIDDEN</Password>
</Login>
<!--Zero or more repetitions:-->
<Orders>44753668</Orders>
<Status>All</Status>
</v22:GetOrders>
</soapenv:Body>
</soapenv:Envelope>
Non working PHP request:
<?php
$wsdl = "https://shop.textalk.se/webservice/v22/?WSDL";
$client = new SoapClient($wsdl, array(
'Shop'=>'23946',
'Username'=>'user#mysite.com',
'Password'=>'HIDDEN',
'trace'=>1,
'exceptions'=>0));
$request = array(
'GetOrdersResponse' => array(
'Orders' => '44753668',
'Status' => 'All'
),
);
$response = $client->GetOrders($request);
var_dump($response);
echo $response;
?>
Documentation is here: https://shop.textalk.se/webservice/v22/wsdldoc.php
When I run the php code absolutely nothing happens
I am not a PHP expert but have you tried the below code?
<?php
$wsdl = "https://shop.textalk.se/webservice/v22/?WSDL";
$client = new SoapClient($wsdl);
$request = array(
'Shop'=>'23946',
'Username'=>'user#mysite.com',
'Password'=>'HIDDEN',
'Orders' => '44753668',
'Status' => 'All'));
$response = $client->GetOrders($request);
var_dump($response);
echo $response;
?>
Check out this blog post for a good starting point http://www.vankouteren.eu/blog/2009/03/simple-php-soap-example/
Note: the code is untested!
I found out what was wrong. I had to pass the login values as an array, and not as separate values. That solved it. I am now getting correct data in return.
<?php
$wsdl = "https://shop.textalk.se/webservice/v22/?WSDL";
$client = new SoapClient($wsdl);
$request = array(
'Login' => array(
'Shop'=>"23946",
'Username'=>"mail#mysite.com",
'Password'=>"HIDDEN"),
'Orders' => "44753668",
'Status' => "All");
$response = $client->GetOrders($request);
var_dump($response);
echo $response;
?>

PHP SoapClient target namespace not in request params

I am using PHP SoapClient in WSDL mode.
This is what the expected SOAP request should look like:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://xml.m4u.com.au/2009">
<soapenv:Header/>
<soapenv:Body>
<ns:sendMessages>
<ns:authentication>
<ns:userId>Username</ns:userId>
<ns:password>Password</ns:password>
</ns:authentication>
<ns:requestBody>
<ns:messages>
<ns:message>
<ns:recipients>
<ns:recipient>61400000001</ns:recipient>
</ns:recipients>
<ns:content>Message Content</ns:content>
</ns:message>
</ns:messages>
</ns:requestBody>
</ns:sendMessages>
</soapenv:Body>
</soapenv:Envelope>
And this is what PHP SoapClient is sending:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://xml.m4u.com.au/2009">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns1:sendMessages>
<ns1:authentication>
<userId>Username</userId>
<password>Password</password>
</ns1:authentication>
<ns1:requestBody>
<messages>
<message>
<recipients>
<recipient>61400000001</recipient>
</recipients>
<content>Message Content</content>
</message>
</messages>
</ns1:requestBody>
</ns1:sendMessages>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This is how I constructed the client and params:
function sendMessages($recipient, $content) {
$authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT);
$recipientsType = new SoapVar(array('recipient' => $recipient), SOAP_ENC_OBJECT);
$messageType = new SoapVar(array('recipients' => $recipientsType, 'content' => $content), SOAP_ENC_OBJECT);
$messagesType = new SoapVar(array('message' => $messageType), SOAP_ENC_OBJECT);
$requestBodyType = new SoapVar(array('messages' => $messagesType), SOAP_ENC_OBJECT);
$params = array(
'authentication' => $authenticationType,
'requestBody' => $requestBodyType
);
try {
$this->soapClient = new SoapClient($this->wsdl, array('trace' => 1));
$this->soapClient->__setSoapHeaders(array());
return $this->soapClient->sendMessages($params);
} catch (SoapFault $fault) {
echo '<h2>Request</h2><pre>' . htmlspecialchars($this->soapClient->__getLastRequest(), ENT_QUOTES) . '</pre>';
trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);
}
}
Why is 'ns1' present for 'authentication' and 'requestBody' but missing for their child nodes?
What am I doing wrong? The WSDL is located here => http://soap.m4u.com.au/?wsdl
Appreciate anyone who can help.
You must specify the URI of the namespace to encode the object. This will include everything necessary (including your missing namespace). The acronym of the namespace name is irrelevant.
This:
$authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT);
should be:
$authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT, "authentication","http://xml.m4u.com.au/2009");
The problem you're seeing with the namespace serialization comes from using soapvar without all the parameters. When it serializes the request prior to sending it assumes the namespace is already included. If, instead, you had created each as a simple array and included them in $params it would include the namespace for the internal parameters correctly. By way of demonstration:
$authenticationType = array('userId' => $this->username, 'password' => $this->password)
try using nusoap library. Below is sample code:
<?php
$wsdl = "http://soap.m4u.com.au/?wsdl";
// generate request veriables
$data = array();
$action = ""; // ws action
$param = ""; //parameters
$options = array(
'location' => 'http://soap.m4u.com.au',
'uri' => ''
);
// eof generate request veriables
//$client = new soap_client($wsdl, $options);// create soap client
$client = new nusoap_client($wsdl, 'wsdl');
$client->setCredentials($api_username, $api_password);// set crendencials
$opt = $client->call($action, $param, '', '', false, true);
print_r($opt);
?>

Categories