Rate this post

When a specific integration involves one organisation/user, with one or more clients (in the server-client sense), this is the ideal use of 2-legged OAuth — where the client and server are known to each other. The basic premise of this is that since the client application is owned by the user, the user doesn’t have a need to authorise the application, the client and server just need to verify that they are who they say they are. We can skip the authorisation process and just sign our requests with a uniquely identifying signature. This has many benefits, including removing the need to repeatedly log in and verify an application, and longer term tokens.

For private application types in Xero, we use 2-legged OAuth with RSA-SHA1 signing method. In a nutshell, 2-legged OAuth uses a public and private key pair, and RSA-SHA1 is the particular method used to generate a client signature from your private credentials that can then be used the sign network requests. A certificate file (public key) is uploaded to the server. Then when a request is made by the client, the server already knows who the client is and vice versa, because requests are signed with the client’s private key. This all sounds great, but is a little bit tricky to achieve in Android due to most of the more popular OAuth libraries using HMAC signing method. Not to worry though, I spent way too long figuring out how to do this, so that you don’t have to. In this tutorial I’ll demonstrate 2-legged OAuth with RSA-SHA1 signing on Android.

First you will need to generate the public and private keys and certificate. This part is pretty standard and as with other java implementations, you definitely want to do this in the .pcks8 format rather than .pem format if you don’t want to have to fiddle around with java extensions that may or may not work and overrides for the java key length policies (as you may have guessed, I definitely spent way too long following this red herring). Assuming that you don’t want to do that, however, here’s how to do it with OpenSSL:

  1. openssl genrsa -out xero_privatekey.pem 1024
  2. openssl req -newkey rsa:1024 -x509 -key xero_privatekey.pem -out xero_publickey.cer -days 365
    The .cer will be needed when creating the API application in the Xero Developer Centre ‘Add Application’ screen
  3. Extract the private key in PKCS8 format: openssl pkcs8 -topk8 -nocrypt -in xero_privatekey.pem -out xero_privatekey.pcks8

This can be found in the Xero Developer documentation.

Now you can upload the .cer file to Xero developer dashboard, and it’ll spit out a consumer key and a secret for you, as per the Getting Started Guide.

A lot of the popular OAuth libraries for Android all use the HMAC signing method. Fortunately, scribe-java has a RSA Signing Service! So let’s add this to our build.gradle file. Since we are making our own API file for this, just add the core project to your dependencies:

compile 'com.github.scribejava:scribejava-core:2.8.1'

Now we can build a custom API class for Xero, based on the default OAuth1.0a class from scribe-java:

https://medium.com/media/62920767ee3d5ed418f7d08628e1cbc3/href

The top half of this API file is the standard file, but all the override methods have been altered to return null. The last half is where this starts to differ from a standard scribe API class. The xero_privatekey.pcs8 file you’ve made before — if you put it in the top level directory of your android project and click on it, AS will open it like a standard text file. You’ll see the key in there, flanked by this useless stuff: “ — — -BEGIN RSA PRIVATE KEY — — -” “ — — -END RSA PRIVATE KEY — — -”. Copy and paste the middle stuff and ignore the header and footer. So now you’ve got your Base64 encoded key string. The code above does the following things with it:

  1. Get a KeyFactory and Specify that its an RSA type one.
  2. Generate the specs for a private keys from the decoded private key string.
  3. Give those specs to the KeyFactory and get a PrivateKey back.

Now you can override the “getSignatureService” method and tell it that you want to use the RSASha1SignatureService with that private key.

Note: It’s worth mentioning that this is only something I would do if you trust the phones this is going on. If these are company phones, used for workplace activity and you know that they have standard ROMs, then this is perfectly fine. However, if you are using these instructions for an application that’s going to be used on iffy phones, probably don’t store keys in your files, because they could be extracted from the .apk on a maliciously rooted phone. The alternative solution here is to use a secure keystore. That’s also quite fiddly and has several more gotchas than this example. So that deserves a whole blog post of its own.

Now we can go to the Android activity where we want to make this call and set up the API.

You’ll need some attributes:

private XeroAPI api;
private OAuth10aService service;
private OAuth1AccessToken accessToken;
private TextView mContent;

Then you can initialise them:

mContent = (TextView) findViewById(R.id.contentText);

//Xero Api initialisation
api = new XeroAPI(getApplicationContext());
service = new ServiceBuilder()
.apiKey(getString(R.string.api_key))
.build(api);

accessToken = new OAuth1AccessToken(getString(R.string.api_key), getString(R.string.api_secret));

Now there are a couple of ways in which this differs from a standard scribe-java OAuth implementation. Firstly, do not initialise the service with a secret, you only need the key. Also, this is the Consumer Key from the dashboard, not the Private Key. Secondly, the Access Token is also created with that Consumer Key, but it additionally needs the Consumer Secret (also available on the dashboard).

As always with Android, all network requests have to be on a separate thread, so we’ll create an async task. There are additionally a couple of packaged asynchronous http libraries that you can use with scribe-java, however in the process of retrofitting the signing service to them they appear to have lost their elegance and any benefit, so we’ll just go with AsyncTask for this basic example. This is a rudimentary example of a signed request:

//Android requires this to be on a separate thread
private class getOrganisation extends AsyncTask<String, Void, String> {

@Override
protected String doInBackground(String…params) {
OAuthRequest request = new OAuthRequest(Verb.GET, “https://api.xero.com/api.xro/2.0/Organisation”, service);
request.addHeader(“Accept”, “application/json”);
service.signRequest(accessToken, request);

Log.d(“Status”, “Requesting…….”);

String responseString = “”;

try {
Response response = request.send();
responseString = response.getBody().toString();
return responseString;
} catch (Exception e) {
e.printStackTrace();
Log.d(“Exception”, “Xero ” + e.getLocalizedMessage());
}

return responseString;
}

@Override
protected void onPostExecute(String result){
Log.d(“Xero Result”, result);
mContent.setText(result);
}
}

I’ve also added a header to tell the API that I want results in JSON, because the default for Xero is XML and I want to take advantage of easy JSON parsing with GSON. I assign the response string to a TextView for this demonstration. In your app you will obviously be handling error codes way more elegantly than in this example :-D.

Then to call this:

//call the async task
new getOrganisation().execute();

The fully working code for this example is here: link.

Consumers of the Xero API include our many fantastic partner add-ons and publicly available integrations, as well as fully customised private applications. Businesses that are committed to automating their business, are able to use the Xero API to develop highly customised applications tailored to the unique needs of their processes, people and environment. This type of integration would be ideal for something like a workforce mobility app, in industries where staff are on the move, and not behind a desk, such as warehouses, drivers and retail and hospitality workers. Of course you could have a mobile app that that integrates with your own server side code that consumes the Xero API, but this may be unnecessary for your specific use case. As demonstrated here, it is also possible to integrate your mobile app directly with the Xero API.

Over the next few months I’ll be working on building a wrapper libraries for Android and iOS use of the Xero API. If you would like to contribute to either of these projects, you can contact me on twitter @coder_bec or via my Github.


Creating Native Android Mobile Apps That Integrate Directly with the Xero API was originally published in Xero Developer on Medium, where people are continuing the conversation by highlighting and responding to this story.