If you don’t use token authentication that is!
Many of our SOAP API integration partners do not provide a valid custom user agent, which makes it very hard for us to contact these integration partners in case we encounter problems. In order to offer better support for your integrations, the following will apply:
From November 16th 2015 we require that all SOAP API requests include a valid X-EconomicAppIdentifier header. From this date we will start rejecting all requests made by your app, if you do not include this header.
This requirement only applies if you are connecting to the SOAP API with…
Please notice
For users of the “Connect” method, we strongly recommend switching to our token authentication. In SOAP this is done via the ConnectWithToken method.
Setting the X-EconomicAppIdentifier header
A valid X-EconomicAppIdentifier header uniquely identifies the integration partner and the app used. A good example of this is:
X-EconomicAppIdentifier: MyCoolIntegration/1.1 (http://example.com/MyCoolIntegration/; MyCoolIntegration@example.com) BasedOnSuperLib/1.4
It first identifies the name and version of the app, and then goes on to supply a link to where more information can be found as well as a contact email. At the end it states the name and version of the library used to access the api. This could be something like PHP-SOAP or Python-httplib.
Here’s an example code when using .NET Service Reference to consume the API:
1 2 3 4 5 6 7 8 |
using (var operationScope = new OperationContextScope(session.InnerChannel)) { // Add a HTTP Header to an outgoing request var requestMessage = new HttpRequestMessageProperty(); requestMessage.Headers["X-EconomicAppIdentifier"] = "MyCoolIntegration/1.1 (http://example.com/MyCoolIntegration/; MyCoolIntegration@example.com) BasedOnSuperLib/1.4"; OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage; session.Connect(<agreement>, <user>, <password>); } |
If you are using the SDK, you must supply the user agent in the Session class constructor. You do not need to state that you are using the SDK. The SDK will append that information itself.
Can I test that my header is correct?
Yes. We’ve added a test endpoint to SOAP that you can check against. It’s called Verify_XEconomicAppIdentifier and returns true if set up correctly. If it is not correctly set up an exception will be thrown. This is the same exception we will throw once we start enforcing the rule.
What happens if I don’t add this header?
If you use token authentication then nothing. But November 16th 2015 we will start rejecting all requests made by your app, if you do not include this header.
Will it be possible to test these changes before November 16th?
Hi Kasper, good question and thanks for pinging us on the matter.
We’ll create a method in SOAP that can test your header. It’ll return true/false. In case of false, our API consumers can contact api@e-conomic.com for further details.
The method will be ready in a week’s time.
Hi Kasper,
The test method is now live.
See documentation here:
https://api.e-conomic.com/secure/api1/EconomicWebService.asmx?op=Verify_XEconomicAppIdentifier
Thanks!
We need a PHP example. Can you provide one please? 🙂
Hi PHP Developers – If you use PHP > 5.3
Then you can use:
$client = new SoapClient ( “https://api.e-conomic.com/secure/api1/EconomicWebService.asmx?WSDL”, [
‘stream_context’ => stream_context_create([‘http’ => [‘header’ => ‘X-EconomicAppIdentifier: YOUR APP IDENTIFIER’]])
]);
What about the PHP Version 5.3.10 ?
Hey Kasper,
Do you have a PHP solution that works with PHP 5.2?
Have an old custom build website where it is not currently possible to upgrade to 5.3. I have tried extending the SoapClient to use cURL, but it does not seem it work. I still get an exception when testing the app identify header. The code is
class SoapClientCURL extends SoapClient {
public function __doRequest($request, $location, $action, $version, $one_way = NULL) {
$soap_request = $request;
$header = array(
“Content-type: text/xml;charset=\”utf-8\””,
“Cache-Control: no-cache”,
“Pragma: no-cache”,
“SOAPAction: \”” . $action . “\””,
“Content-length: ” . strlen($soap_request),
“X-EconomicAppIdentifier: YOUR APP IDENTIFIER”,
);
$soap_do = curl_init();
$url = $location;
$options = array(
CURLOPT_HTTPHEADER => $header,
//CURLOPT_HEADER => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_SSL_VERIFYHOST => FALSE,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_USERAGENT => ‘PHP/’ . phpversion(),
CURLOPT_URL => $url,
//CURLOPT_VERBOSE => TRUE,
CURLOPT_POSTFIELDS => $soap_request,
);
curl_setopt_array($soap_do , $options);
$output = curl_exec($soap_do);
if($output === FALSE) {
$err = ‘Curl error: ‘ . curl_error($soap_do);
print $err;
exit;
}
curl_close($soap_do);
return parent::__doRequest($request, $location, $action, $version);
}
}
Can you send a mail to api@e-conomic.com with the error code you get. That will allow us to see exactly why your request fails.
Hi,
We are on php 5.2. We cannot upgrade for a lot of reasons.
I’m trying:
$header = new SoapHeader(‘http://e-conomic.com’,
‘X-EconomicAppIdentifier’,
‘MyCoolIntegration/1.1 (http://example.com/MyCoolIntegration/; MyCoolIntegration@example.com) BasedOnSuperLib/1.4′);
$this->client->__setSoapHeaders($header);
Which generates the following request:
MyCoolIntegration/1.1 (http://example.com/MyCoolIntegration/; MyCoolIntegration@example.com) BasedOnSuperLib/1.4
Which gives me the following error:
Economic.Api.Exceptions.AuthorizationException(E03100): You need to include an X-EconomicAppIdentifier header when not connecting with the Token Based model. Read more at https://www.e-conomic.com/developer. (id=c9122905-a3b2-4ad2-b04b-3761e9978a66)
Can you help me?
Hi Jesper
I’ve just had a look at your request in the log. You’re including the AppIdentifier in your payload.
You need to add the X-EconomicAppIdentifier to the HTTP Headers. Not the SOAP header.
The XML request to Verify_XEconomicAppIdentifier needs to match the documentation https://api.e-conomic.com/secure/api1/EconomicWebService.asmx?op=Verify_XEconomicAppIdentifier
Can I test this by simply replacing ‘https://api.e-conomic.com/secure/api1/EconomicWebService.asmx?wsdl’ with ‘https://api.e-conomic.com/secure/api1/EconomicWebService.asmx?op=Verify_XEconomicAppIdentifier’ in my request?
Hi Kjeld
https://api.e-conomic.com/secure/api1/EconomicWebService.asmx?op=Verify_XEconomicAppIdentifier is a link to the documentation for the endpoint.
https://api.e-conomic.com/secure/api1/EconomicWebService.asmx?wsdl is the web service definition list for your integration.
You need to call the function Verify_XEconomicAppIdentifier() in your code in order to verify your header.
Hello – good approach for good support. Question: Can we already add the new header in production or do we have to wait until Nov. 16th. ?
Hi Henrik
Thank you for your question.
We would love to see you implement this today rather than wait 🙂
The header is fully supported for production use.
Thanks!
Hi,
For whose who work in C# with web reference (wsdl) and don’t want to add the header on every request but want this done automatically for them here is something that would help you:
———————————————————————————————————————————————
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;
using EConomicSOAP.EconomicWebService;
namespace EConomicSOAP
{
public class EconomicSoapClient
{
private const string webServiceUrl = @”https://api.e-conomic.com/secure/api1/EconomicWebService.asmx”;
public static EconomicWebServiceSoapClient GetEconomicSoapClient(string appIdentifier)
{
var binding = new BasicHttpBinding
{
AllowCookies = true,
Security = {Mode = BasicHttpSecurityMode.Transport},
MaxReceivedMessageSize = Int32.MaxValue,
};
var endpointAddress = new EndpointAddress(webServiceUrl);
var client = new EconomicWebServiceSoapClient(binding, endpointAddress);
client.Endpoint.EndpointBehaviors.Add(new EconomicSoapServiceBehavior(appIdentifier));
return client;
}
}
public class EconomicSoapServiceBehavior : IClientMessageInspector, IEndpointBehavior
{
private string _appIdentifier = String.Empty;
public EconomicSoapServiceBehavior(string appIdentifier)
{
_appIdentifier = appIdentifier;
}
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
{
WriteOutgoingHttpHeader(request, “X-EconomicAppIdentifier”, _appIdentifier);
return null;
}
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(this);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{}
public void Validate(ServiceEndpoint endpoint)
{}
private static void WriteOutgoingHttpHeader(Message request, string name, string value)
{
HttpRequestMessageProperty httpRequestMessage;
object httpRequestMessageObject;
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
{
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (string.IsNullOrEmpty(httpRequestMessage.Headers[name]))
{
httpRequestMessage.Headers[name] = value;
}
}
else
{
httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers[name] = value;
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
}
}
}
We are using the SDK v1.4.20, and have now added the AppIdentifier to the constructor call for EconomicSession class.
Is this all that has to be done? All our existing SDK calls remain exactly as-is?
Can I trust that the identifier automatically works with the SDK on November 16th, or is it possible to somehow test it beforehand? The test endpoint you listed is not really of much use when using the SDK?
Hi Morten
If you are successfully connecting with SDK v1.4.20 then you are in the clear.
Should want an absolute confirmation then please contact the API support and we’ll be happy to confirm your AppIdentifier string in our logs.
Is it possible to add the header in the app.config or web.config files in endpoint?
hi jhross.
The header needs to be added to your http request. How you do this is up to you but as far as I can tell IIS only allows you to set response headers.
You need to set a request header.
We’ve had a working solution to this for two months, including a function that calls Verify_XEconomicAppIdentifier everytime we connect to e-conomic. It suddenly started throwing exceptions yesterday morning, claiming the header is not correct. Has anything been changed in the API around that time?
The exception:
Economic.Api.Exceptions.AuthorizationException(E03100): You need to include an X-EconomicAppIdentifier header when not connecting with the Token Based model. Read more at https://www.e-conomic.com/developer. (id=e11f63bc-45e5-4c36-acb8-449d5a86f23d)
I am seeing the same thing. I have only just implemented the header and I can see that it is indeed being sent in the request headers, but I am thrown the same exception with Verify_XEconomicAppIdentifier().
Have experienced the same issue when testing an upgrade to PHP 5.3 today. According to the support do they experience problems with the Verify_XEconomicAppIdentifier() method. They are working on fixing the issue.
Hi all.
Verify_ is back on track by 16:40 today.
For PHP-SOAP, I presume we should give the version of PHP, since a version number for the SOAP extension does not seem readily available?
Hi Lech
If you’re referring to the example of “BasedOnSuperLib/1.4” then it makes sense to add PHP version. Yes.
Hi Martin,
Please would you be able to publish a java connection example?
Thanks,
Brian
Hi Brian
This is quite dependant on your choice of client so it can be difficult to answer easily.
I’ve inserted an example below
If you’re using Axis, it seems you could do it like so:
// Create an instance of org.apache.axis2.client.ServiceClient
ServiceClient client = …
// Create an instance of org.apache.axis2.client.Options
Options options = new Options();
List list = new ArrayList();
// Create an instance of org.apache.commons.httpclient.Header
Header header = new Header();
// Http header. Name : user, Value : admin
header.setName(“X-EconomicAppIdentifier”);
header.setValue(“MyCoolIntegration/1.1 (http://example.com/MyCoolIntegration/; MyCoolIntegration@example.com) BasedOnSuperLib/1.4″);
list.add(header);
options.setProperty(org.apache.axis2.transport.http.HTTPConstants.HTTP_HEADERS, list);
client.setOptions(options);
Reference: http://stackoverflow.com/questions/12071798/how-to-add-a-http-header-to-a-soaprequest-in-java
If we create a customer specific solution that is not a specific, general app, will we then need an app identifier for each customer solution or is the AppIdentifier connected to us as the partner so that the appIdentifier can be reused for differenct customer specific solutions?
Hi Lars
Thank you for asking that question.
The AppIdentifier is meant to be unique for each unique integration that you create. It is also meant to be a common tool for you and us to establish communication and help in debugging.
All customer data relating to the individual agreement is already available to e-conomic so shouldn’t be added to the AppIdentifier.
Hi,
we are using the e-conomic .NET API v. 1.4.15 on a simple .NET web page using C#.
We tried to add the header before calling connect() but we get the following error:
Fejlmeddelelse om kompileringsfunktion: CS1061: ‘Economic.Api.EconomicSession’ indeholder ikke en definition til ‘InnerChannel’, og der blev ikke fundet en udvidelsesmetode ‘InnerChannel’, der accepterer et første argument af typen ‘Economic.Api.EconomicSession’ (mangler du en ‘using’-direktiv eller en assemblyreference?)
private string Connect()
{
using (var operationScope = new OperationContextScope(_session.InnerChannel))
{
// Add a HTTP Header to an outgoing request
var requestMessage = new HttpRequestMessageProperty();
requestMessage.Headers[“X-EconomicAppIdentifier”] = “MyCoolApp/1.1 (http://www.mybusiness.com/mycoolapp; mycoolapp@mycoolbusiness.com) BasedOnSuperLib/1.4″;
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
return _session.Connect(, , );
}
}
Also can you provide code for token based access in C#?
We have registered a developer account and got the token id created to use with our agreement.
regards
Thomas
Hi Thomas
You must upgrade to at least SDK DLL v.1.4.18.
Get the latest SDK release here: https://github.com/e-conomic/eco-api-sdk
We are connecting using the 1.4.14 dll.
Could you please inform me of the changes we are required to make?
Hi Carsten
Please upgrade to at least SDK v1.4.18 and make sure to add an AppIdentifier string to the session constructor. Read more on the GitHub page.
Get the latest SDK release here: https://github.com/e-conomic/eco-api-sdk (currently 1.4.21)
Using the v1.4.21 version of the SDK, EconomicSession.VerifyXEconomicAppIdentifier() returns true even with an empty userAgent.
Also, are we supposed to make up our own user agents for our apps, or do they need to match some registered ones at your end?
Hi Jannick – Thanks for the heads-up. We’ve just released v1.4.22 where we also fixed that issue now we were at it. You are indeed supposed to write your own appIdentifier. We’d appreciate if you follow the gist of the example of this blog post. The most important part is that you supply valid contact information and a name for your solution.
When will requests without X-EconomicAppIdentifier be rejected?
Pingback: New deadline for X-EconomicAppIdentier HTTP header
Hi Kjeld,
We’ve moved the deadline. Read more here: http://techtalk.e-conomic.com/new-deadline-for-x-economicappidentier-http-header/