2
votes

I'm new to Oauth and I stack on getting oauth_access_token to work with Xero. Web Service authentication doesn't work for me. Xero returns the following error message "oauth_problem=signature_invalid&oauth_problem_advice=Failed to validate signature". The generated signature is incorrect, but what is right way to generate it?

Here is APEX code which generates Endpoint. What is wrong?

Http h = new Http();
String consumer_key='XXX';
Long tmp=(System.now().getTime()/1000);

Blob isItCorrect = Crypto.generateMac('HMacSHA1', Blob.valueOf('https://api.xero.com/api.xro/2.0'), Blob.valueOf(consumer_key));
String signature= EncodingUtil.urlEncode(EncodingUtil.base64Encode(isItCorrect), 'UTF-8');

// Try to get access token
HttpRequest req = new HttpRequest();
req.setEndpoint('https://api.xero.com/oauth/RequestToken?oauth_consumer_key='+consumer_key+
        '&oauth_signature_method=RSA-SHA1'+
        '&oauth_signature='+signature+
        '&oauth_timestamp='+tmp+ '&oauth_nonce='+tmp+'&oauth_version=1.0&scope=https%3A%2F%2Fapi.xero.com%2Fapi.xro%2F2.0');
req.setMethod('GET');

// Send the request, and return a response
HttpResponse res = h.send(req);
System.debug('~~~ '+res.getBody());

It generates following Endpoint: Endpoint=https://api.xero.com/oauth/RequestToken?oauth_consumer_key=ICSP7Y5K2TG7RIIC6Y7R7KLC1AHWYC&oauth_signature_method=RSA-SHA1&oauth_signature=gWP02y2EIatw4xilTvd5Iq3e0%2Fw%3D&oauth_timestamp=1372123781&oauth_nonce=1372123781&oauth_version=1.0&scope=https%3A%2F%2Fapi.xero.com%2Fapi.xro%2F2.0

1
Did you solve this problem... I am trying to call external web service (Xero) in Apex by setting up Oauth settings....can you help me with it?Yogesh D

1 Answers

1
votes

Just as an aside: I've never worked with salesforce so I'm not sure if there's a better way to leverage existing oauth work on the platform, it's very rare now to have to write all the oauth signature stuff yourself and it's easy to make a mistake but here goes]

I think your signature base string is incorrect.

As far as I can tell you're just performing HMAC-SHA1 over https://api.xero.com/api.xro/2.0

if you read the OAuth Spec here: http://oauth.net/core/1.0/#anchor14 you need to construct the following base string (based on the request above)

GET&https%3A%2F%2Fapi.xero.com%2Foauth%2Frequesttoken&oauth_consumer_key%3DCONSUMER_KEY%26oauth_nonce (etc etc, just append all your query parameters apart from oauth_consumer as url encoded key=value pairs, in alphabetical order)

and then you need to create the hash with the key CONSUMER_KEY&CONSUMER_SECRET (both CONSUMER_KEY and CONSUMER_SECRET should be parameter encoded as per the OAuth Spec)

That should give you a valid signature..

Edit: I found this library which might be of help: https://code.google.com/p/sfdc-oauth-playground/