I am trying to access a Magento API, using SOAP. the code I have works fine normally, however the client wishes to password protect the Magento main folder. Doing so breaks access to the API and causes an error.
The documentation suggests this isnt a problem and you can just specify the username/password, however this does not work.
I am using PHP and IIS, with the password protection set up via Plesk 10. Does this use Basic HTTP authentication or something else?
My access code is:
$client = new SoapAuthClient($GLOBALS["magento_api_path"],array(
'login'=>"admin",
'password'=>"password"
)
);
$session = $client->login($GLOBALS["magento_api_user"], $GLOABLS["magento_api_password"] ,
array(
'login'=>"admin",
'password'=>"password"
) );
The error I get is:
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.domain.co.uk/magento/index.php/api/index/index/wsdl/1/' : failed to load external entity "http://www.domain.co.uk/magento/index.php/api/index/index/wsdl/1/" in C:\Inetpub\vhosts\domain.co.uk\httpdocs\backend\index.php:20 Stack trace: #0 C:\Inetpub\vhosts\domain.co.uk\httpdocs\backend\index.php(20): SoapClient->__call('login', Array) #1 C:\Inetpub\vhosts\domain.co.uk\httpdocs\backend\index.php(20): SoapClient->login('backenduser', 'backendwebuser', Array) #2 {main} thrown in C:\Inetpub\vhosts\domain.co.uk\httpdocs\backend\index.php on line 20
The line referred to is the $client->login command.
Any suggestions?
I've faced a similiar problem long time ago.
In my case, I didn't immediately realize that I need to use .htaccess credentials while creating the SoapClient instance, but pass SOAP API credentials to the login method.
I was passing the SOAP API credentials all over and got a similiar error like you do.
Here's what worked for me (1.3.x version, though. Still works for me as of today):
$cProxy = new SoapClient(
URL . 'index.php/api/soap/?wsdl',
array(
'login' => HTACCESS_USER,
'password' => HTACCESS_PASS
)
);
$rSessionId = $cProxy->login(
SOAP_USER,
SOAP_PASS
);
Just to play save, that you are didn't got trapped by a typo: you pass $GLOABLS["magento_api_password"] as 2nd param to the login method, which should be $GLOBALS["magento_api_password"].
Finally, you're passing a 3rd argument to the login method which I believe is obsolete, since afaik it's defined to have two params only:
<message name="login">
<part name="username" type="xsd:string" />
<part name="apiKey" type="xsd:string" />
</message>
Been there, done that :P
$client = new SoapClient("http://${http_user}:${http_pass}#subdomain.domain.com", array(
'login' => $user,
'password' => $pass,
));
The problem is that the use of the http auth only happens during the requests and not while actually fetching the wsdl on the first request. To get around that, simply use the format i posted above: http://USERNAME:PASSWORD#server.com/
Cheers
This problem is likely because internally Magento is requesting, via a local HTTP request, it's own WSDL. As you've password protected the access, it's not going to work. Modify the security to not require a password if the request is coming from localhost.
If you look at Mage_Api_Model_Server_Adapter_Soap::getWsdlUrl() you will see, that magento assumes that basic auth login and password are passed as environment variables PHP_AUTH_USER and PHP_AUTH_PW.
Related
I am connecting to dynamics 365. It used to work perfectly, i curl to get the token then i use it as an authorization header along with php soapclient and it works, i connect i create a client and i can call my methods.
All of a sudden it decided not to work, and where it used to connect as SOAP 1.1 now it enforced SOAP 1.2
After changing from SOAP 1.1 to SOAP 1.2 ( because I got the error of binding mismatch where it said expecting application/soap+xml and text/xml was found ) So I changed versions and that error disappeared and got replaced with ERROR Fetching HTTP Headers.
That error got stuck for the longest time, people suggested to increase timeout but i put it as high as 500 800 5000 all the same.
Then all of a sudden, it started giving me SOAP ERROR Parsing schema element already defined. I did not change my code, i played for awhile with the headers but to no avail, I even removed the authorization header just to see what is going on and that did nothing i kept getting the same error.
SOAP-ERROR: Parsing Schema: element 'http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.Ax.Xpp:XppObjectBase' already defined [string:Exception:private]
everytime I try to connect I get different kind of parsing schema error even though i am not changing anything in my code:
SOAP-ERROR: Parsing Schema: element 'http://schemas.microsoft.com/2003/10/Serialization/:anyType' already defined [string:Exception:private]
and another
SOAP-ERROR: Parsing Schema: element 'http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.AX.KernelInterop:ProxyBase' already defined [string:Exception:private]
and then sometimes it does get through for a second but with fetching http header error again..
so i can not create a client instance anymore now..
where before i was able to create a client instance but i get an error when I call the method of "Error Fetching HTTP Headers"
something is definitely not stable because my errors are not one.
now some stated the wsdl could be faulty, but this is microsoft and the person i am in contact keeps saying he can not doing anything about it.
Help is this a PHP problem or a dynamics problem or wsdl custom made problem .
And how to solve this.
Thank you.
UPDATE
I'm sorry I mentioned earlier it is Dynamics AX , it turns out it is Dynamics 365 D365. I will keep dynamics ax tag in case it helps someone who needs the solutions provided.
UPDATE
Following is the connection code I am using:
function getAuthenticationHeader()
{
//Each variable has the values for our server
//resource
$appResource = urlencode($appADResource);
//clientID
$appClientID = urlencode($appADClientId);
//appSecret
$appSecret = urlencode($appADSecret);
//username
$appUserID = urlencode($appUserID);
// Password
$appUserPassword = urlencode($password);
// Construct the body for the STS request
$authenticationRequestBody = 'resource='.$appResource.'&client_id='.$appClientID.'&client_secret='.$appSecret.'&grant_type=password&username='.$appUserID.'&password='.$appUserPassword.'&scope=openid';
//Using curl to post the information to STS and get back the authentication response
$ch = curl_init();
// set url
$stsUrl = 'https://login.microsoftonline.com/'.$appTenantId.'/oauth2/token';
curl_setopt($ch, CURLOPT_URL, $stsUrl);
// Get the response back as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set the parameters for the request
curl_setopt($ch, CURLOPT_POSTFIELDS, $authenticationRequestBody);
// By default, HTTPS does not work with curl.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// read the output from the post request
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
// decode the response from sts using json decoder
$tokenOutput = json_decode($output);
return $tokenOutput->{'token_type'}.' '.$tokenOutput->{'access_token'};
}
try
{
//WSDL Link
$url = "https://urlToOurServer/services/webservice?wsdl";
$authorizationToken = getAuthenticationHeader();
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
),
'https' => array(
'curl_verify_ssl_peer' => false,
'curl_verify_ssl_host' => false
),
'http' => array(
'header' =>'Authorization: '.$authorizationToken
)
));
//Create array of Soap Options
$arrOpt = array(
"soap_version" => SOAP_1_2,
"cache_wsdl" => WSDL_CACHE_NONE,
"exceptions" => true,
'trace' => true,
'encoding' => 'UTF-8',
'stream_context' => $context
);
}catch(Exception $e)
{
print_r($e);
}
I also found this in my wsdl
<sp:IssuedToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<sp:RequestSecurityTokenTemplate>
<trust:TokenType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
</trust:TokenType>
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer
</trust:KeyType>
</sp:RequestSecurityTokenTemplate>
<wsp:Policy>
<sp:RequireInternalReference/>
How can I connect to SAML for Token ?
If everything is pretty much the same, but it's not working, the first thing to do is rule out the most basic AX issues. These may not solve your issue but will be a good first step.
now some stated the wsdl could be faulty, but this is microsoft and the person i am in contact keeps saying he can not doing anything about it.
Whomever that person is, you need to confirm they've done the following:
Confirm the environment and specifically the CIL is fully compiled. Do a full AXBuild and a full CIL to be sure during non-business hours and ensure the output is good. It's basically saying "recompile everything".
Refresh the WCF configuration in the client configuration you are using to connect to AX. This client configuration may be a *.axc file or it may just be the active one. Also refresh the business connector WCF. This is separate and may be what you are using to connect to AX. This is what most people are talking about.
Here's a little article that talks about creating a configuration, but I'll discuss below.
An AX client configuration ultimately is a bunch of text. It's either stored in an .axc file or stored in the registry in a few locations. The Business Connector client config may be the one that is getting missed in your scenario.
If you follow the link above and create a new .axc configuration file and ensure you've clicked "Refresh Configuration" before exporting, when you open the file up in Notepad, you'll see wcfconfig and a bunch of XML following it. That XML is what you're trying to get updated. Creating a new AXC here is just an exercise to help you understand what it is. You can delete the file after you're done looking.
Now, you've basically created a specific configuration file, but that doesn't mean anything is using it. If you call AX32.exe it will default to the one that is loaded in that config screen. Using a file is a way to very specifically choose one. Your code is probably using a specific AXC somewhere that needs either replaced or refreshed OR it's using one that's saved in this window:
It is very likely it is using one of the two that are saved in that configuration window. When you refresh in that window, it ultimately saves the WCF XML in the windows registry on the machine that is hosting the client and/or the AOS in subfolders in HKLM\SOFTWARE\Microsoft\Dynamics\6.0\Configuration. The key(s) is wcfconfig paired with wcfconfigversionid, which just stores a GUID to see if it's up-to-date.
When I say two, I mean most people don't even bother to look at the Business Connector AXC. It's what is highlighted in yellow in my image, and you need to specifically choose and refresh it. This could be important for you. In my image, I do not have it chosen. You need to drop the menu down and choose it.
On a dev machine, you can just clear both of those keys and refresh and you should see whatever configuration you're working on update.
This is a long post, but it's important to rule this part out first. If you have someone who's reasonably experienced administering AX they should know how to ensure these are refreshed.
Since you're saying this is not Dynamics AX, but one of the Dynamics 365 versions. The AX version used to be called Dynamics 365 for Finance and Operations Enterprise Edition but they've changed the licensing/naming again, so I don't even know what it's technically called. Most people call it Dynamics 365 for Operations or some variant.
Either way, you should test the service following the below method. We would need to see more information about the service details and call, so following the below is most likely best.
https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/third-party-service-test
I'm implementing OpenId Connect into my Yii2 app using the yii2-authclient library. I can login and exchange the code for a token with no problems. I've followed most of the code examples on the web and set a successCallback function that gets called once a user successfully logs in. It looks like this:
public function successCallback(ClientInterface $client)
{
$attributes = $client->getUserAttributes();
}
This code gets called, but calling getUserAttributes() results in the following error:
Exception – yii\authclient\InvalidResponseException
Request failed with code: 400, message:
{"error":"invalid_request","error_description":"Token not provided"}
The logs on the id server show a blank client and user, with an error of invalid_token.
I took a close look at the request I make and I see an access_token element. Any ideas what the problem might be? I can provide more information if necessary.
I figured it out. The problem was that the yii2-authclient library was sending the token as a GET parameter and the ID server was expecting it as a POST param. I upgraded the yii2-authclient library and that solved the problem since a recent change sends the parameter as POST instead of GET.
I am using https://twitteroauth.com/ in my some PHP pages. I want to get user access token and access secret token. I got my answer on this page: How to get user Access Token and Access Secret with the Twitter API using php
After replacing my consumer key and secret consumer key on both pages. I upload it on my server but then I got the following error when I open twitter-go.php
Fatal error: Uncaught exception `'Abraham\TwitterOAuth\TwitterOAuthException'` with message
'<?xml version="1.0" encoding="UTF-8"?>
<hash>
<error>Desktop applications only support the oauth_callback value 'oob'</error>
<request>/oauth/request_token</request>
</hash> '
in `/home/mediahyp/public_html/tweetme/twitteroauth/src/TwitterOAuth.php:138`
Stack trace:
#0 /home/mediahyp/public_html/tweetme/twitter-go.php(13): Abraham\TwitterOAuth\TwitterOAuth->oauth('oauth/request_t...', Array)
#1 {main} thrown in /home/mediahyp/public_html/tweetme/twitteroauth/src/TwitterOAuth.php on line 138
Can anyone tell me what is this error about? Am I missing something or something else.
https://twittercommunity.com/t/desktop-applications-only-support-the-oauth-callback-value-oob-oauth-request-token/252/2
The new interface simplifies this: if you provide a placeholder callback URL in the field for it in your application detail screen, it allows you to use dynamic callbacks. So just go ahead and put a placeholder in there (doesn't have to be the actual dynamic/runtime callback you use) and you'll be able to use other forms of auth.
When no placeholder is presented, the application is locked to OOB mode.
I am working on an api for a client. I have received the following information:
API Url: http://xyz-crm.example/WebAPI/Custom/project_name/XML/
Username: foobar
password: spameggs
I need to configure the PHP SOAP client for the same in non-WSDL mode. I have written the following but it does not seem to work:
$wsdl = null;
$options = array(
'uri' => 'http://xyz-crm.example/WebAPI/Custom/project_name/XML/',
'location' => 'http://xyz-crm.exmaple.com/WebAPI/Custom/project_name/XML/',
'login' => 'foobar',
'password' => 'spameggs'
);
$client = new SoapCLient($wsdl, $options);
I just want to make a successful ping to the api at first. See if things are working fine. What am I doing wrong here?
Update 1
I made the following changes:
$wsdl = null;
$options = array(
'uri' => "http://xyz-crm.example/WebAPI/Custom/project_name/XML/",
'location' => "http://xyz-crm.example/",
'Username' => "foobar",
'Password' => "spameggs",
'soap_version' => '1.2'
);
$client = new SoapClient($wsdl, $options);
$client = $client->getListings();
I get the error: looks like we got no XML document
[Edit by me, hakre: This update was done as feedback to answer #1. It changes the location option using a shortened URL (reason not given by OP) and it adds the soap_version option (as suggested in answer #1, but not as constant but as string (containing an invalid value), so there should be no wonder this creates an error, a correct option value is given in answer #1 (the SOAP_1_1 constant) and by intention, the correct value would be the SOAP_1_2 constant for this example). Error message as commented by OP was "SOAP Fault: Wrong version."]
Update 2
I tried the following but it still fails:
$listing = $client->getListings();
$request = $client->__getLastRequest();
The execution stops at the first line itself without ever going to the second one.
[Edit by me, hakre: As review has shown wrong configuration options in Update 1 already which are not addressed in Update 2 it would be a miracle if it still wouldn't fail. The execution stops because an Exception is thrown and no error/exception handling is done]
Die URI or file ending does not matter, it could even be .jpg, there is no default.
Have a look at similiar questions: Does this SOAP Fault mean what I think it means?
It would be helpful if you put the error message into the question, aswell as the XML output of your request.
try setting the SOAP Version in the array of your SoapClient instance to one of the constants (try different ones):
new SoapClient($url, array("soap_version" => SOAP_1_1,.......
or SOAP_1_2 ...
To debug the XML try the answer from Inspect XML created by PHP SoapClient call before/without sending the request
The error message of your updated question does not look like it coming from PHP, looks more like an answer from the webservice, means your request is actually working.
I am feebly trying to implement a stamps.com api interface into my platform. This is my first time using SOAP, I event had to recompile PHP to enable the libraries.
I'm moving along but now I'm having a problem. They support soap 1.1 and soap 1.2 requests, and when I run the following code:
$client = new SOAPClient(
'./SWSIM.wsdl',
array(
'trace' => 1
)
);
I get back a successful response from my request that comes after this.
However if I add the option to use soap 1.2 like this:
$client = new SOAPClient(
'./SWSIM.wsdl',
array(
'trace' => 1,
'soap_version' => SOAP_1_2
)
);
I get the following error:
There was an exception running the extensions specified in the config file. ---> Value cannot be null. Parameter name: input
This line is not actually throwing the exception. Its the following command that throws it, but removing the soap_version is what "fixes it". I would like to use soap 1.2 so naturally this is bugging me.
FTR The command I'm running is this:
$authData = array(
"Credentials" => array(
"IntegrationID" => "MYUID",
"Username" => "MYUSERNAME",
"Password" => "MYPASSWORD"
)
);
try {
$objectresult = $client->AuthenticateUser($authData);
} catch (Exception $e) {
echo "EXCEPTION: " . $e->getMessage();
print_r($e);
exit;
}
The WSDL file can be viewed here:
https://swsim.stamps.com/swsim/swsimv22.asmx?wsdl
I have also checked in with their developer support and they said:
"The message you are currently receiving is returned from whichever program you are designing your integration with. This has been commonly noted happening within Visual Basic where is creates a wrapper class that needs certain variables for the response. This could be similar to the behavior that you are experiencing. Please verify how your program language consumes a WSDL."
I also noticed that the __soapCall method excepts an "input headers" argument. I'm not entirely sure I should be / can even use that method in my code. I suppose I should just try and play with it.
Check your WSDL file. I was using the wrong one, and it appears you may be as well. Try this one: http://developer.stamps.com/developer/downloads/files/Stamps.com_SWSIM.wsdl
NOTE: The above is out of date. Contact stamps.com for the current wsdl!
I know this is an old thread, but here is an example class that should get anyone started with the stamps.com api in php https://github.com/aaronjsmith/stamps.com-php
The WSDL looks fine and it's the same input structure for both Soap versions. The problem is a bug somewhere at their end, you'll have to contact them to resolve.
I would also test it via a .NET app just to see if it behaves the same.