ma77c
ma77c

Reputation: 1086

PHP | SOAP 1.2 | How to set WS Addressing

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 ...

Upvotes: 3

Views: 4325

Answers (3)

Mehmet Ali kandemir
Mehmet Ali kandemir

Reputation: 51

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);
    

Upvotes: 0

Neeraj Yadav
Neeraj Yadav

Reputation: 41

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

Upvotes: 4

Rick
Rick

Reputation: 1

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);
} 

Upvotes: 0

Related Questions