tip
How to authenticate the call to a SOAP web service with PHP 5+
Below is the authenticated request we want to build. It carries a username and password authentication header.
SOAP XML request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Header>
<m:SOAPAuthenticationHeader xmlns:m="http://www.mydomain.com">
<m:username>myusername</m:username>
<m:password>mypassword</m:password>
</m:SOAPAuthenticationHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<m:WebServiceMethodName xmlns:m="http://www.mydomain.com">
<m:param1>some value</m:param1>
<m:param2>some value</m:param2>
<m:param3>some value</m:param3>
</m:WebServiceMethodName>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
When we have to use SOAP authentication headers to call a service, we cannot use the intuitive way below, because all of the fields go inside the body part of the envelope (SOAP-ENV Body):
1
2
3
4
5
6
7
8
|
<?php
$params = new StdClass();
$params->Header->username = "myusername";
$params->Header->password = "mypassword";
$params->Body->param1 = "some value";
$params->Body->param2 = "some value";
$params->Body->param3 = "some value";
|
The object above is not encoded as a SOAP request with header envelope and body envelope parts - it is simply encoded as body envelope part with child elements header and body. And the request is not properly authenticated.
The solution is to create a separate object to carry the authentication header envelope and a separate object for the body envelope.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<?php
define(WSDL_URL, "http://www.mydomain.com/webservicepath?wsdl");
# create authentication headers (SOAP Header envelope)
$params_header = new stdClass();
$params_header->username = "myusername";
$params_header->password = "mypassword";
# create request parameters (SOAP Body envelope)
$params = new stdClass();
$params->param1 = "some value";
$params->param2 = "some value";
$params->param3 = "some value";
# create soap client object
$soap_client = new SoapClient(WSDL_URL, array("connection_timeout"=>5, 'trace'=>1));
# create soap header object
$soap_header = new SoapHeader("http://www.mydomain.com", "SOAPAuthenticationHeader", $params_header);
# instruct the client to use the SOAP headers we prepared
# when calling the service
$soap_client->__setSoapHeaders(array($soap_header));
try
{
# call the method of the service
$result = $soap_client->WebServiceMethodName(params);
}
catch(SoapFault $exception)
{
echo $exception;
}
|