PHP | SOAP 1.2 | How to set WS Addressing

4.1k views Asked by At

Here is the WSDL ...

I am using the SOAP Client in PHP with documentation HERE ...

Soap Call

$wsdl = 'https://api.krollcorp.com/EBusinessTest/Kroll.Dealer.EBusiness.svc/Docs?singleWsdl';

try {
    $client = new SoapClient($wsdl, array('soap_version' => SOAP_1_2, 'trace' => 1));
    // $result = $client->SubmitPurchaseOrder();
    $result = $client->__soapCall("SubmitPurchaseOrder", array());
} catch (SoapFault $e) {
    printf("\nERROR: %s\n", $e->getMessage());
}

$requestHeaders = $client->__getLastRequestHeaders();
$request = $client->__getLastRequest();
$responseHeaders = $client->__getLastResponseHeaders();
printf("\nRequest Headers -----\n");
print_r($requestHeaders);
printf("\nRequest -----\n");
print_r($request);
printf("\nResponse Headers -----\n");
print_r($responseHeaders);
printf("\nEND\n");

Output

ERROR: The SOAP action specified on the message, '', does not match the HTTP SOAP Action, 'http://tempuri.org/IEBusinessService/SubmitPurchaseOrder'.

Request Headers -----
POST /EBusinessTest/Kroll.Dealer.EBusiness.svc HTTP/1.1
Host: api.krollcorp.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.6.19
Content-Type: application/soap+xml; charset=utf-8; action="http://tempuri.org/IEBusinessService/SubmitPurchaseOrder"
Content-Length: 200


Request -----
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://tempuri.org/"><env:Body><ns1:SubmitPurchaseOrder/></env:Body></env:Envelope>

Response Headers -----
HTTP/1.1 500 Internal Server Error
Content-Length: 637
Content-Type: application/soap+xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 06 Sep 2017 12:42:57 GMT

END

Attempts

I am a beginner at using SOAP APIs.

I believe this is failing because SOAP 1.2 uses WsHttpBinding instead of BasicHttpBinding.

I am not sure how to set WS Addressing with the SOAP Client in PHP ...

3

There are 3 answers

0
Mehmet Ali kandemir On

My solution is

  1. Send request using SoapUi
  2. Copy request http log from SoapUi screen ( Bottom of SoapUi program)
  3. Past that code into the PHP project as fallows

    $soap_request = '{copy that part from SoapUi http log}';

        $WSDL = "**wsdl adres**";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HEADER,         false);
        curl_setopt($ch, CURLOPT_URL,            $WSDL);
        curl_setopt($ch, CURLOPT_FAILONERROR,    true);
        curl_setopt($ch, CURLOPT_HTTPHEADER,     Array(
            'Content-Type: application/soap+xml; charset=utf-8',
            'SOAPAction: "run"',
            'Accept: text/xml',
            'Cache-Control: no-cache',
            'Pragma: no-cache',
            'Content-length: '. strlen($soap_request),
            'User-Agent: PHP-SOAP/7.0.10',
        ));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_TIMEOUT,        30);
        curl_setopt($ch, CURLOPT_POSTFIELDS,     $soap_request);
        $response = curl_exec($ch);
        if (empty($response)) {
            throw new SoapFault('CURL error: '.curl_error($ch), curl_errno($ch));
        }
        curl_close($ch);
    
0
Rick On

Dude, I totally feel your pain. I was able to get this to work but I don't think this is the right way, but it is pointing in the right direction. A caveat though, you have to know what namespace soap_client is going to assign to the addressing. Best way is just to capture the request XML and look for what namespace is attache to the addressing, and then pass it in. Below is my code with a default of 'ns2' for namespace, but you can't count on it for your example. Good Luck!

private function generateWSAddressingHeader($action,$to,$replyto,$message_id=false,$ns='ns2')
{
    $message_id = ($message_id) ? $message_id : $this->_uniqueId(true);
    $soap_header = <<<SOAP
        <{$ns}:Action env:mustUnderstand="0">{$action}</{$ns}:Action>
        <{$ns}:MessageID>urn:uuid:{$message_id}</{$ns}:MessageID>
        <{$ns}:ReplyTo>
          <{$ns}:Address>{$replyto}</{$ns}:Address>
        </{$ns}:ReplyTo>
        <{$ns}:To env:mustUnderstand="0">$to</{$ns}:To>
SOAP;
    return new \SoapHeader('http://www.w3.org/2005/08/addressing','Addressing',new \SoapVar($soap_header, XSD_ANYXML),true);
} 
9
Neeraj Yadav On

Below code is working for me.You can enable Ws-A Addressing and call soap method-

$client = new SoapClient("http://www.xyz.Services?Wsdl", array('soap_version'   => SOAP_1_2,'trace' => 1,'exceptions'=> false
    ));
    $wsa_namespace = 'http://www.w3.org/2005/08/addressing';
    $ACTION_ISSUE = 'http://www.xyx/getPassword';// Url With method name
    $NS_ADDR = 'http://www.w3.org/2005/08/addressing';
    $action = new SoapHeader($NS_ADDR, 'Action', $ACTION_ISSUE, true);

    $to = new SoapHeader($NS_ADDR, 'To', 'http://www.xyx.svc/Basic', false);
    $headerbody = array('Action' => $action,'To' => $to);
    $client->__setSoapHeaders($headerbody);


    //$fcs = $client->__getFunctions();
    //pre($client->__getLastRequest());
//pre($fcs);

$parameters=array('UserId'=>'12345678','MemberId'=>'123456','Password' => '123456','PassKey' => 'abcdef1234');
;
$result = $client->__soapCall('getPassword', array($parameters));//getPassword method name
print_r(htmlspecialchars($client->__getLastRequest()));// view your request in xml code

print_r($client->__getLastRequest());die; //Get Last Request

print_r($result);die; //print response