Hello,
From some of my posts you’d figure I had a big project, where many problems occurred between SOAP PHP and other services..yeah it happened.
I had to implement connections with various security protocols, the other day at StackOverflow I noticed someone having problem with this, and most of the posts have no responses at all.
This specific post will show you to establish a connection to a SOAP WebService that is secured with WSSE, the specific doc is Web Services Security Username Token Profile: http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
In order to structure it clearly, and make sure PHP doens’t f*ck while generating the XML, we create various classes.
First we need a Class to store our username and password.
1 2 3 4 5 6 7 8 |
class WSSEAuth { private $Username; private $Password; function __construct($username, $password) { $this->Username= $username; $this->Password= $password; } } |
Then we need a class to store our Username Token related to this service.
1 2 3 4 5 6 7 8 9 |
class WSSEToken { private $UsernameToken; function __construct($innerVal) { $this->UsernameToken = $innerVal; } } |
Now instead of extending the SoapClient, which made errors happened in other places of communication with various other SOAP APIs.
I just make client inside another class, with the security options prepared and then return it to be used elsewhere in the code.
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 34 35 36 37 38 39 40 41 42 43 44 |
class MySoapClient { private $username; private $password; private $options; private $header; private $wsdl; private $wsse; private $gw; public $start_time; public function getClient($wsse, $user, $pw, $wsdl, $gw) { $this->wsse = $wsse; $this->username = $user; $this->password = $pw; $this->wsdl = $wsdl; $this->gw = $gw; $this->start_time = microtime(true); $this->options = array( 'trace'=>1, 'username'=>$this->username, 'password'=>$this->password, 'exceptions'=>true, 'connection_timeout'=>5, ); $objSoapVarUser = new SoapVar($this->username, XSD_STRING, NULL, $this->wsse, NULL, $this->wsse); $objSoapVarPass = new SoapVar($this->password, XSD_STRING, NULL, $this->wsse, NULL, $this->wsse); $objWSSEAuth = new WSSEAuth($objSoapVarUser, $objSoapVarPass); $objSoapVarWSSEAuth = new SoapVar($objWSSEAuth, SOAP_ENC_OBJECT, NULL, $this->wsse, 'UsernameToken', $this->wsse); $objWSSEToken = new WSSEToken($objSoapVarWSSEAuth); $objSoapVarWSSEToken = new SoapVar($objWSSEToken, SOAP_ENC_OBJECT, NULL, $this->wsse, 'UsernameToken', $this->wsse); $this->header = new SoapVar($objSoapVarWSSEToken, SOAP_ENC_OBJECT, NULL, $this->wsse, 'Security', $this->wsse); $objSoapVarWSSEHeader[] = new SoapHeader($this->wsse, 'Security', $this->header, true, $this->gw); $objClient = new SoapClient($this->wsdl, $this->options); $objClient->__setSoapHeaders($objSoapVarWSSEHeader); return $objClient; } } |
I have trace, exceptions and connection_timeout activated which are all optional.
After all those 3 classes are created, I can just access my prepared client like this:
1 2 |
$var = new MySoapClient; $var_client = $var->getClient('http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', 'your_user', 'your_password', 'your_wsdl', 'your_gate'); |
Obvious as it seems, you need to indicate your user, pw, wsdl and gate (optional) to connect.
Afterwards you use it just as normal, example:
1 |
$var_client->__soapCall('Function', $soap_payload); |
Hope this comes in handy for some of you..
Happy coding!