+ Start a Discussion
James Grummell 9James Grummell 9 

Using oAuth in Force.Com to access an External Application

I am attempting to connect to an external application using Execute Anonymous in the Developer Console.
The application is using 2-Legged oAuth so I am encoding the signature in RSA-SHA1. Despite this, I seem to keep getting the result "Invalid Signature". Can anyone tell me if I am missing essential formatting in my code below for using oAuth?
Any help is greatly appreciated. I have also modified the Consumer Key and Private Key from thier true values, but maintained thier Size and special characters for a reference.

Http h = new Http();
String consumer_key='A1BF9UW7HS67STUOW8HUMKWODSJUOS';
//Encoded PKCS8 Private Key
//Composed of Private Key Generated by OpenSSL
String secret_key='MIICXAIBAAKBgQDF9IiOjP0ZQcqGQ+Ut8K4Ug4vWe7' +
    'M6TRF+ruvVv1CtMOfZVV3kvtJPaNAD/bBs8W5wVFD+' +
    'tg+YhKL2nxkEKssdDNuyIOUa9OOQPbEBIjM7IJ8bRh' +
    '3kycneA0GPuNQIB3n5leCeCZtg56OR2WC8udc2FklQ' +
    'Jpvm0GWy+mvXC+DaewIDAQABAoGAce4+lgTROrMh88' +
    '0JCVugy1G/3UYfyxLeb26hVFPASmE635DRrLgbrjFL' +
    'qp4ZnvJwFa/1PxUWvso/3L9Or5ZNlmerHkdOdQhS3N' +
    'aUxDlB0RsCV7kwRVhaJbwsBKL07bYHqHCB3BE97xoN' +
    'Ak4ptsfEXYALeRnegSfpeq72fZGnYnECQQDrjPrfjH' +
    '9n5C60AfYgotQW6F52kHB6posgzltuTWh8UMaZUVD+' +
    'Td+mcDYIIlJnmG1qyL+v3Eu+CbBLDhY8HuXqNAbQCQ' +
    'RQkwEl1wGbrnyLeaKNH9t1yYmYwm93K+Vu9jAkEA1y' +
    'QCNs1A+IzbiUacbq1nzrstSzOdBCnLOeWBZRByqeYa' +
    'r6awJBANN5TcPYlli6/ME/a11Pjo6jZq5ZGaqR+nX6' +
    'JAeFJikDDPn/0yUicyV8d1OWJnZn8vxacvKIngsH6A' +
    'IgiM+iJMkiYnpFOtQScTj3S7PNcfNVAlz5mXuwvppA' +
    'pupU9KEU0h5iDRSXx/8UyUgHpcOWyKLewPp9FAnQyW' +
    'AF1+U0HSECQBVzu8CVaK7keNdOhHSgIsvCEdjzzA1P' +
    'd4uHbwGLObtCcxz2nwymQD4GZ8UMDZWLnX3/V2JbvQ' +

Long tmp=(System.now().getTime()/1000);

String encrypt_string = 'GET&https%3A%2F%2Fapi.xero.com%2Fapi.xro%2F2.0%2FContacts' +
                        '&oauth_consumer_key%3D' + consumer_key +
                        '%26oauth_nonce%3Dfef295f8188b8686fc922a66ec4fed2b' +
                        '%26oauth_signature_method%3DRSA-SHA1' +
                        '%26oauth_timestamp%3D' + tmp +
                        '%26oauth_token%3D' + consumer_key +

String algorithmName = 'RSA-SHA1';
String key =  secret_key;

// Decode the key from base64 to binary
Blob privateKey = EncodingUtil.base64Decode(key);
Blob input = Blob.valueOf(consumer_key);
Blob signature = Crypto.sign(algorithmName, input, privateKey);

String signatureA = EncodingUtil.base64Encode(signature);
String signatureB = EncodingUtil.urlEncode(signatureA, 'UTF-8');
System.debug('~~~ '+ signatureA);

// Try to get access token
HttpRequest req = new HttpRequest();
req.setEndpoint('https://api.xero.com/api.xro/2.0/Contacts' +
                        '?oauth_consumer_key=' + consumer_key +
                        '&oauth_nonce=fef295f8188b8686fc922a66ec4fed2b' +
                        '&oauth_signature=' + signatureB +
                        '&oauth_signature_method=RSA-SHA1' + 
                        '&oauth_timestamp=' + tmp +
                        '&oauth_token=' + consumer_key +               

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

nitin sharmanitin sharma

I am nor sure if it going to help u or not.However,I was able to do OAuth with the below given code.I only did the initial authorization and then stopped as I did not need it any further.

This aouth is from visual force page in one org to another salesforce org.

public with sharing class authclass {
public static final string CLIENT_SECRET=' "';//
public static final string CLIENT_ID='' ";
public static final string REDIRECT_URL=' ";
public static final string OAUTH_TOKEN_URL=' "';
public static final string OAUTH_CODE_END_POINT_URL="";
//public static final string grant_type=authorization_code';

   /*'grant_type=password' +
            '&client_id=' + clientId +
            '&client_secret=' + clientSecret +
            '&username=' + EncodingUtil.urlEncode(username, 'UTF-8') +
            '&password=' + EncodingUtil.urlEncode(password, 'UTF-8'));*/

    public PageReference Establish() {

     String x=OAUTH_CODE_END_POINT_URL+'?redirect_uri='+EncodingUtil.urlEncode(REDIRECT_URL,'UTF-8')+'&response_type=code&client_id='+CLIENT_ID+'&grant_type=Authorize_code'+'&Client_secret='+client_Secret;   
     pagereference p=new pagereference(x);
     return p;
Shankish NairShankish Nair

Did you get solution for this? 

I am trying for the the same Oauth of XERo within salesforce.

Jorel NaidooJorel Naidoo
I know this is a little late but this may help someone in the future. 

// Decode the key from base64 to binary
Blob privateKey = EncodingUtil.base64Decode(key);
Blob input = Blob.valueOf(encrypt_string); // This is the value that needs to be signed instead of consumer_key
Blob signature = Crypto.sign(algorithmName, input, privateKey);

Also the secret_key need to be a valid pksc8 format key

Hi Jorel,

I've tried your code but am still stuck at "failed to validate signature" 
Have you updated your code since? are you able to connect successfully?

Have you able to authenticate with Xero?
I have tried to copy the oauth signature that is generated using Xero's Net sample application, and use it in my apex code. Then also it fails to bring contacts from Xero.

If anybody has authenticated from Salesforce to Xero, can they please give some suggestions?