Nick Poulos
Nick Poulos

Reputation: 488

PHP SoapClient - Unauthorized Operation Exception - Request formed properly?

I am trying to access a 3rd-party GPS tracking SOAP WebService to return a list of our company vehicles. I have been looking through the documentation for the SoapClient object and reading many examples here at StackOverflow, but I am still not sure how to make this operation work.

$api_key='xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$service_url = http://api.remotehost.com/RemoteService.svc?wsdl

That is the WSDL for the service I am attempting to access, I am trying to access the GetVehicles() method. When I create a new client using:

$client = new SoapClient($service_url, array('cache_wsdl' => 0));

I am able to run $client->__getFunctions(), which correctly lists all of the service's functions. However, when I try to access the GetVehicles method using:

$vehicles=$client->GetVehicles($api_key);
var_dump($vehicles);

I am getting an "Attempted to perform an unauthorized operation" error. I am not sure if this means the request is being formed incorrectly, or if I am accessing the wrong URL, or what is going on exactly. Should I be accessing this using the __soapCall or __doRequest methods of SoapClient? If you look at the WSDL, you can see other action URLS for specific operations, should I be using those somewhere?

To try and debug, I am using the program SoapUI. I enter in the WSDL URL, and the program pulls in the function list and I can issue requests from there. When I make a request using GetVehicles, I get the correct listing results back, so I know there is not an authentication issue.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:api="http://api.remotehost.com">
   <soapenv:Header/>
   <soapenv:Body>
      <api:GetVehicles>
         <!--Optional:-->
         <api:APIKey>xxxxxxxxxxxxxxxxxxxxxxxx</api:APIKey>
      </api:GetVehicles>
   </soapenv:Body>
</soapenv:Envelope>

Which DOES return the correct vehcile listing XML. I am very confused as to what I am doing wrong, and I am running out of time to get this done. Can anybody help point me in the right direction and let me know how I should be making this SOAP request? Any help is greatly appreciated. Thank you!

Upvotes: 1

Views: 1644

Answers (2)

ladenedge
ladenedge

Reputation: 13419

You'll need to specify how the $api_key value is to be used, like so:

$client->GetVehicles(array('APIKey' => $api_key));

To add a bit of explanation, your call here:

$client->GetVehicles($api_key);

Doesn't tell the client how to use $api_key. If you look at the output of __getFunctions(), you'll see that GetVehicles takes a certain type of parameter structure:

GetVehiclesResponse GetVehicles(GetVehicles $parameters)

To see what that parameter structure is, you'd have to issue a __getTypes() call. Here's the relevant line:

struct GetVehicles { string APIKey; }

This means what you want to pass your GetVehicles call is actually a structure with a single member. Fortunately PHP is nice and will accept an array with matching names.

A useful way to debug this is to use Fiddler as a proxy for your calls. (If you're not on Windows, you can do something similar with Wireshark.) Load up Fiddler, then construct your SoapClient like this:

$opts = array('proxy_host' => 'localhost', 'proxy_port' => 8888);
$client = new SoapClient($wsdl, $opts);

Then all of the calls you make though the client will show up in Fiddler for you to examine. Your original call, for example, shows up in Fiddler as:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="http://api.silentpassenger.com">
    <SOAP-ENV:Body>
        <ns1:GetVehicles/>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Seeing that your APIKey element wasn't present might have given you a helpful clue about what was wrong.

Upvotes: 2

Dimitri
Dimitri

Reputation: 7013

Try this:

$vehicles=$client->GetVehicles(array('APIKey' => $api_key));

Upvotes: 2

Related Questions