0

I am trying to make a php client from a wsdl, that consumes a WCF service. I have managed to consume the web service with a C# console application by only passing the credentials(no pem certification needed).

The url for the wsdl is the following(it is a test environment):

https://extenavigator.ukho.gov.uk/serviceB2B/submitUKHOOrdering.svc?wsdl

So If someone wants to try to create a soap client use this wsdl.

"Attempting to access with an account that is lacking the relevant service permission will result in a response with a ProcessResult.Failure Acknowledgement and a Message added to the Messages property of: The service [serviceName] is not available to the user [userId]" (from the provider).

So a working soap client with wrong credentials should return the above message.

In order to create a soap client in php first I created the stub classes via wsdl2phpgenerator. Then I instantiate the soap client as below:

ini_set('max_execution_time', 480);
ini_set('default_socket_timeout', 400);

$orderServiceClient = new OrderingService(array('login' => DIST_B2B_USERNAME, 'password' => DIST_B2B_PASSWORD, "trace"=>1, 
"exceptions"=>1, 'cache_wsdl' => WSDL_CACHE_MEMORY, 'soap_version' => SOAP_1_2, 'keep_alive' => false, 
"connection_timeout" => 240, 'verifypeer' => false, 'verifyhost' => false, "ssl_method" => SOAP_SSL_METHOD_TLS));

where OrderingService is the stub class that extends SOAP client class.

At last I call a method like this:

$getHoldingsRequest = new GetHoldingRequest(DIST_ID, 25555, ProductType::AVCSCharts); // set some params for the called method

$responce = $orderServiceClient->GetHoldings($getHoldingsRequest); // call the method

The error I get is: Error Fetching http headers

I have enabled ssl in php.ini and in the apache conf file. I am using a windows PC.

I have read this posts:

Connecting to WS-Security protected Web Service with PHP

SoapFault exception: [HTTP] Error Fetching http headers

I figure out that the problem is that the soap header must be customized in order to pass the credentials ("Username and Password authentication over SSL")

I have also tried to create custom soap headers:

 class WsseAuthHeader extends SoapHeader 
{
    private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd';
    function __construct($user, $pass, $ns = null) 
    {    
    if ($ns) 
    {        
        $this->wss_ns = $ns;    
    }    

    $auth = new stdClass();    

    $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);     
    $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);    
    $username_token = new stdClass();    
    $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns);     
    $security_sv = new SoapVar(        
                            new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),        
                            SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);    

    parent::__construct($this->wss_ns, 'Security', $security_sv, true);
    }
}

and

 $wsse_header = new WsseAuthHeader("xxxx", "xxxx");

 $orderServiceClient = new OrderingService(array('trace' => true, 'exceptions' => true, 'cache_wsdl' => WSDL_CACHE_MEMORY, 
'soap_version' => SOAP_1_2, 'keep_alive' => false, 'connection_timeout' => 240));

 $orderServiceClient->__setSoapHeaders(array($wsse_header));

Finally

$getHoldingsRequest = new GetHoldingRequest(DIST_ID, 25555, ProductType::AVCSCharts);
 $getHoldingsRequest->setRequestId($GUID);

try {
$responce = $orderServiceClient->GetHoldings($getHoldingsRequest);

} catch (Exception $e) {
echo $e->getMessage();
}


 echo "<pre>" . var_export($orderServiceClient->__getLastRequest(), TRUE) . "</pre>";

I get:

Error Fetching http headers

NULL

I have also tried other things mentioned in the above posts with no result.

From the posts mentioned above:

"But as I said above: I think that much more knowledge about the WS-Security specification and the given service architecture is needed to get this working."

So if someone has experience with soap client and is able to create a php client for this wsdl that would be a great help.

For GUID I used the following function:

  function getGUID(){
if (function_exists('com_create_guid')){
    return com_create_guid();
}else{
    mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
    $charid = strtoupper(md5(uniqid(rand(), true)));
    $hyphen = chr(45);// "-"
    $uuid = chr(123)// "{"
        .substr($charid, 0, 8).$hyphen
        .substr($charid, 8, 4).$hyphen
        .substr($charid,12, 4).$hyphen
        .substr($charid,16, 4).$hyphen
        .substr($charid,20,12)
        .chr(125);// "}"
    return $uuid;
   }
}

   $GUID = getGUID();
Community
  • 1
  • 1
Jim
  • 21
  • 3

1 Answers1

0

I am new and not sure my post will be helpful or not but I will try to help you - If you have already got your WSDL file or URL then

-you can use php SoapClient

  • kindly ignore ,if post is not matching your requirement

Try to follow example give below and also your WSDL file structure(holding function and parameter via XML)

Its up to you, can put step 1 and step 2 code inside class/function, or can use in simple given way.

Step 1-

try {

$client = new SoapClient(SOAP_CLIENT_WSDL_URL, array('soap_version' => SOAP_VERSION, 'trace' => true)); return $client;

} catch (SoapFault $fault) {

trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);

die();

}

Step 2-

result = $client->your_wsdl_containing_function("follow_wsdl_parameter")

$xml_last_response = $client->__getLastResponse();

echo '';print_r($xml_last_response);

Pankaj
  • 1
  • 3
  • Can you be more detailed about step 2? Do I have to combine step1 and step 2? – Jim Aug 16 '16 at 10:08
  • you can put step 1 code inside initialize_soap_client(), then in step 2 you can see it is called,and then object soapclient can be used to call function which is inside wsdl, atlast you will receive your final response/xml,then convert xml response into array – Pankaj Aug 17 '16 at 00:51
  • Now already updated answer, there is no initialize_soap_clie‌​nt() , you can use it in a simple way, also suggest you to see you request_response also before last_response for debugging – Pankaj Aug 17 '16 at 01:01
  • I edited the question. In case you(or someone else) wants to try to consume the mentioned service. – Jim Aug 17 '16 at 08:35