PHP WSDL SOAP Can't Import Schema - php

I'm trying to use an external webservice but I get the error Parsing Schema: can't import schema from webservice_url. The service uses HTTP Basic authentication and is using SSL. I can login via a web browser and see the xml it produces but I can't change what is generated since it is not my code generating the xml. I have the following code.
$config = array('login' => $user_id, 'password' => $password);
$client = new SoapClient($url, $config);

Well after researching and reading a bunch of articles online it seems like this is a limitation of php-soap and some suggestions point at using curl to accomplish. I actually decided to avoid PHP entirely since I just learned Ruby and have been going away from PHP. I accomplished my above task by using the Savon gem which has some pretty good documentation on the authentication and setting the cookie. It works great using this gem.

I found this on the SoapClient manual page's comment section:
<?php
$login = 'someone';
$password = 'secret';
$client = new SoapClient(
'https://' . urlencode($login) . ':' . urlencode($password) . '#www.server.com/path/to/wsdl',
array(
'login' => $login,
'password' => $password
)
);
?>
Seems like the basic authentication is for the endpoint invocation, not the WSDL retrieval.

Related

PHP Soap - Authentication header missing

I have been using an API for a WMS which has updated to include authentication headers. I have been provided some required details but have been unable to sucessfully use the API. I have asked the developers but they are unable to help as they do not use PHP.
Previous to the last update, this would work:
$wsdl = URL_HERE;
$soapClient = new SoapClient($wsdl);
$params = array('customer' => $get_users_company->custcode_code);
$response = $soapClient->GetProducts($params);
With the authentification headers, this is what I currently have which is causing the error Authentication header missing
$wsdl = URL_HERE;
$ns = NAMESPACE_HERE;
$soapClient = new SoapClient($wsdl);
$headerbody = array('ID' => 'PROVIDED_ID_HERE', 'KEY' => 'PROVIDED_KEY_HERE');
$headers = new SOAPHeader($ns, 'AuthHeader', $headerbody);
$soapClient->__setSoapHeaders($headers);
$response = $soapClient->__soapCall("GetProducts", array('customer' => $get_users_company->custcode_code));
I'm not 100% sure I am doing this correctly, but without the last line, I get no errors and the page loads fine (No results). Am I correct in thinking the headers are being sent?
I have heard the good old, "we can't help because we are XML Gods and your little php is beneath us"...but you can still get technical support from them by speaking their XML language. Dump out your actual, raw XML and communicate with them using that - don't mention PHP.
Follow the example here and get your request. Make sure it is matching what the documentation of your API is requesting. If it is, call your technical support and show them your XML. If it isn't, then, you know what you need to fix.
When using $soapClient->__soapCall() the second parameter takes an array, and your data structure is also an array, so you maybe should be doing:
$params = array('customer' => $get_users_company->custcode_code);
$response = $soapClient->__soapCall("GetProducts", array($params));
Or just leave it as:
$response = $soapClient->GetProducts($params);
Which looks nicer.

PHP SoapClient with BasicAuth

I have a PHP script trying to connect to a WSDL.
I need to allow self signed AND give basic auth details.
Using SOAP UI, when I connect to the WSDL I am prompted for username / password.
I got this working.
I also found out that each request also requires basic auth (so on the request screen, I have to select Auth, then basic, enter same credentials as I used on the prompt).
How to I do this auth in PHP
As I said, I can connect, not a problem, I seem to kill the service or timeout if I try to make a request
<?php
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
));
$data = array(
'columnA' => 'dataA',
'columnB' => 'dataB',
'columnC' => 'dataC');
$url = 'https://111.111.111.111:1234/dir/file';
$login = 'username';
$pwd = 'password';
$client = new soapClient(null, array(
'location' => $url,
'uri' => '',
'login' => $login,
'password' => $pwd,
'stream_context' => $context
));
echo "\n\r---connected---\n\r";
$result = $client ->requestName($data);
print_r($result);
?>
My output is
---connected---
Then it seems to hang.
I have tried wrapping it round a try catch and I had the same result.
Any suggestions??
From the Manual soapclient support the http basic auth.
For HTTP authentication, the login and password options can be used to
supply credentials. For making an HTTP connection through a proxy
server, the options proxy_host, proxy_port, proxy_login and
proxy_password are also available. For HTTPS client certificate
authentication use local_cert and passphrase options. An
authentication may be supplied in the authentication option. The
authentication method may be either SOAP_AUTHENTICATION_BASIC
(default) or SOAP_AUTHENTICATION_DIGEST.
$wsdl = "http://example/services/Service?wsdl";
$option = array(
"trace"=>1,
"login"=>"admin",
"password"=>"admin",
);
$client = new SoapClient($wsdl,$option);
But when I initiate the soapclient, it will throw this error
Exception: Unauthorized
I also have tried to put the auth in the url, like
$wsdl = "http://admin:admin#example/services/Service?wsdl";
But it also doesn't works.
Finally I solved it by add authentication to the option. The manual says the authentication default value is the basic auth, but only when I explicitly set it, it can work.
$option = array(
"trace"=>1,
"login"=>"admin",
"password"=>"admin",
"authentication"=>SOAP_AUTHENTICATION_BASIC
);
Try url encoding your username and password inside the url that you are using:
$url = 'http://'.urlencode('yourLogin').':'.urlencode('yourPassword').'#111.111.111.111:1234/dir/file';
Also I don't see you make use of the wsdl in your code example. You can always download a copy of the wsdl locally and then reference that local copy. You can download the wsdl anyway you want (with php, curl, manually).

Connecting to eBay Trading API through SoapClient throws 'The web service eBayAPI is not properly configured or not found and is disabled' exception

I'm trying to connect to the ebay trading API and make a basic request using PHP's SoapClient class, but I'm having trouble. I've done hours of searching for and fiddling with examples, but I cannot get anything to work. So I wrote the following barebones code and I'm trying to get it working:
$token = [token here];
$client = new SOAPClient('http://developer.ebay.com/webservices/latest/eBaySvc.wsdl', array('trace' => 1, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS));
$header = new SoapHeader('urn:ebay:apis:eBLBaseComponents', 'RequesterCredentials', new SoapVar(array('ebayAuthToken' => $token), SOAP_ENC_OBJECT), false);
$client->__setSoapHeaders(array($header));
$method = 'GeteBayOfficialTime';
$parameters = array(
);
try {
$responseObj = $client->__soapCall($method, array($parameters));
}
catch (Exception $e)
{
echo 'Exception caught. Here are the xml request & response:<br><br>';
echo '$client->__getLastRequest():<br><pre><xmp>' . $client->__getLastRequest() . '</xmp></pre>';
echo '$client->__getLastResponse():<br><pre><xmp>' . $client->__getLastResponse() . '</xmp></pre><br>';
echo '<p>Exception trying to call ' . $method . '</p>';
echo '$e->getMessage()';
echo '<pre>' . $e->getMessage() . '</pre>';
}
The output of that is:
Exception caught. Here are the xml request & response:
$client->__getLastRequest():
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ebay:apis:eBLBaseComponents" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Header><xsd:RequesterCredentials><ebayAuthToken>[token was here]</ebayAuthToken></xsd:RequesterCredentials></SOAP-ENV:Header><SOAP-ENV:Body><ns1:GeteBayOfficialTimeRequest/></SOAP-ENV:Body></SOAP-ENV:Envelope>
$client->__getLastResponse():
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <soapenv:Fault> <faultcode>soapenv:Server.userException</faultcode> <faultstring>com.ebay.app.pres.service.hosting.WebServiceDisabledException: The web service eBayAPI is not properly configured or not found and is disabled.</faultstring> <detail/> </soapenv:Fault> </soapenv:Body> </soapenv:Envelope>
Exception trying to call GeteBayOfficialTime
$e->getMessage()
com.ebay.app.pres.service.hosting.WebServiceDisabledException: The web service eBayAPI is not properly configured or not found and is disabled.
Can anyone help me get this working? Part of the problem might be that I have no clue what should go in the first parameter of the SoapHeader function ("namespace").
After hours of hacking other people's examples and trying new stuff on my own, I finally was able to get this working. I'm posting the solution here in case it helps someone else:
$token = '';
$appId = '';
$wsdl_url = 'ebaysvc.wsdl.xml'; // downloaded from http://developer.ebay.com/webservices/latest/eBaySvc.wsdl
$apiCall = 'GetUser';
$client = new SOAPClient($wsdl_url, array('trace' => 1, 'exceptions' => true, 'location' => 'https://api.sandbox.ebay.com/wsapi?callname=' . $apiCall . '&appid=' . $appId . '&siteid=0&version=821&routing=new'));
$requesterCredentials = new stdClass();
$requesterCredentials->eBayAuthToken = $token;
$header = new SoapHeader('urn:ebay:apis:eBLBaseComponents', 'RequesterCredentials', $requesterCredentials);
// the API call parameters
$params = array(
'Version' => 821,
'DetailLevel' => 'ReturnSummary',
'UserID' => ''
);
$responseObj = $client->__soapCall($apiCall, array($params), null, $header); // make the API call
Where the $token, $appId, and UserID are filled in with the appropriate values.
A few notes:
Because exceptions are set to true, the SoapClient constructor call and all soapCall's should be inside of a try/catch block
The siteid parameter is set to 0, which indicates this is for the United States ebay website
The location URL should be changed from api.sandbox.ebay.com to api.ebay.com to use the production environment instead of the sandbox
I decided to download the WSDL file instead of using it remotely because it's very large (about 5MB) and slows down requests significantly
I don't know why a simple example like this isn't available anywhere, but I sure wish it had been when I was trying to figure this out!
Thank you for filing a support request.
I believe, you are looking for an authentication mechanism by which ebay users can authenticate your application to make API calls on their behalf. If this is the case, you have to use the Auth and Auth process, which is infact very simple.
Generate an RuName through your developer account; this is a one time process and your application needs just one RuName.
Make a GetSessionID API call using your key set and passing your RuName in the request
Your application should open a browser window with the following URL : https://signin.ebay.com/ws/eBayISAPI.dll?SignIn&runame=$runame&SessID=$sessionid , Please note that this URL contains the SessionID generated in Step 2 and your RuName.
The user of the application should enter their ebay login credentials and once logged in, Click on I agree button.
Make a FetchToken API call, which returns a token for the ebay user. Use this token to make any other Trading API call to access the ebay user account.
The above process is explained in the following knowledge base article titled, Auth and Auth Quickstart: https://ebay.custhelp.com/app/answers/detail/a_id/1198
(If you search in the same knowledge base you can find sample auth and auth implementation for Java, PHP and .Net)
Here&apos;s more detailed information on the Auth and Auth process: http://developer.ebay.com/DevZone/guides/ebayfeatures/Basics/Tokens-MultipleUsers.html#GettingaTokenviaFetchToken
Here&apos;s an article on generating RuName: http://developer.ebay.com/DevZone/guides/ebayfeatures/Basics/Tokens-SettingUpApp.html#GenerateanRuNameforYourApplication
Please let me know if this helps or if you need further assistance.
Best Regards,
eBay Developer Support

WSO2 WSF/PHP - WSDL w WS-Security Certificate Signing

I am trying to connect to a WSDL that uses WS-Security Certificate Signing over HTTPS.
Only the outgoing messages are signed and it uses Binary Security Token (could not find this specific option in WSO2 but so I am unsure I am using the correct option in the code below).
I have looked at the code in the Samples of the WSO2 WSF/PHP and have joined together the WDSL client example and the Signing example.
Code:
$my_cert = ws_get_cert_from_file("./keys/cert.pem");
$my_key = ws_get_key_from_file("./keys/key.pem");
$sec_array = array("sign"=>TRUE,
"algorithmSuite" => "Basic256Rsa15",
"securityTokenReference" => "EmbeddedToken"); //Is this correct for Binary Security Token?
$policy = new WSPolicy(array("security"=>$sec_array));
$sec_token = new WSSecurityToken(array("privateKey" => $my_key,
"certificate" => $my_cert));
$client = new WSClient(array("wsdl"=>"https://.../Informationservice.WSDL",
"useWSA" => TRUE,
"policy" => $policy,
"securityToken" => $sec_token));
$proxy = $client->getProxy();
$return_val = $proxy->StreetTypes();
Any help would be much appreciated as I haven't been able to find an examples of connecting to a service like this online anywhere. Most services seem to sign with Username and Password rather than Certificates and when looking for WSDL and Certificate Signing I don't find anything at all.
You need to specify the CACert option for https to work with "to" endpoint set to the https endpoint. Also use the non wsdl mode as there are some known issues with wsdl mode.

Jira Soap with a Php

I have seen little to know instruction on using php to develop a client website to make remote calls to JiRA.
Currently I'm trying to make a soap client using JSP/Java to connect to a local jira instance. I would like to create and search issues that is all. We are currently having some problems using Maven2 and getting all the files we need from the repository since we are behind a major firewall(yes I've used the proxy).
I have a lot of experience with PHP and would like to know if using the PHP soapclient calls can get the job done.
http://php.net/manual/en/soapclient.soapclient.php
Yes it can be done, using SOAP or XML-RPC.
Using the APIs is pretty much straight forward - have a look at the API documentation to find the right functions for you. your code should look something like :
<?
$soapClient = new SoapClient("https://your.jira/rpc/soap/jirasoapservice-v2?wsdl");
$token = $soapClient->login('user', 'password');
...
... # get/create/modify issues
...
?>
Example of adding a new comment:
$issueKey = "key-123";
$myComment = "your comment";
$soapClient = new SoapClient("https://your.jira/rpc/soap/jirasoapservice-v2?wsdl");
$token = $soapClient->login('user', 'password');
$soapClient->addComment($token, $issueKey, array('body' => $myComment));
Example of creating an issue:
$issue = array(
'type'=>'1',
'project'=>'TEST',
'description'=>'my description',
'summary'=>'my summary',
'priority'=>'1',
'assignee'=>'user',
'reporter'=>'user',
);
$soapClient = new SoapClient("https://your.jira/rpc/soap/jirasoapservice-v2?wsdl");
$token = $soapClient->login('user', 'password');
$soapClient->createIssue($token, $issue);
Note that you need to install php-soap in linux (or it's equivalent in windows) to be able to use the SOAP library.

Categories