Category Archives: OAuth

OAuth and REST in Android: Part 1

I recently had the fun experience of learning a bit about both OAuth and making REST web service calls in Android and since I didn’t find much good material out there, I thought I would share it here.

oauthpicture thumb OAuth and REST in Android: Part 1

Let’s talk about OAuth

The first thing you NEED to know about OAuth is that OAuth and OAuth 2.0 are not the same protocol.

From the OAuth guide on hueniverse:

OAuth 2.0 is a completely new protocol and is not backwards compatible with previous versions. However, it retains the overall architecture and approach established by the previous versions, and the same introduction (from the Official Guide to OAuth 1.0) still very much applies.

But, before we get into that, let’s talk a little bit about what OAuth is for.

OAuth basically does two things for a web site providing some kind of service or API that another application might want to use.

  1. It prevents the consuming application from needing to store or have the user’s login and password.
  2. It allows for a scoping of access to the producer’s services.  (For example, a user might be able to login to a site and access all of the features, but an app using OAuth might only be granted permissions to do certain things.)

So now that we know why, let’s talk about how both OAuth and OAuth 2 work from a high level perspective.

From the app developer perspective, the flow goes something like this:

  1. You register your application with the service you want to access and get some unique identifiers for your application.
  2. When you want to access something on the service, you make a request to the service using your unique identifier and telling it where to send the user after they authenticate.  (Usually you would launch a browser window here.)
  3. User will login to the service using the browser window you launched for that service and choose to grant your application certain privileges.
  4. The service will redirect the user to the callback url you provided and include a code you can use to get an access token.
  5. You call the service one more time passing in your unique identifier and the code you got back and the service grants you an access token which you can use to access services you have been granted permissions for.
  6. The next time you need to make a call you can just use that access token instead of going through this whole process again.  (At least till it expires.)

It really isn’t that complicated; the basic idea is that you tell the service who you are and ask the user to authenticate themselves and grant permissions to your application.  Then you prove that you got the response from the server and that it is still you and the service gives you a special pass to access the service.

The real difference between OAuth and OAuth 2 is the protocol itself, not the process.  So this is both good and bad.

Good, because we don’t have to change our process flow and understand something different.

Bad, because we can’t use the same libraries to access an OAuth 2 implementation as we do for an OAuth implementation and vice versa.  There is no backwards compatibility.

For the purpose of this post I am going to show how to use the Leeloo library to connect to an OAuth 2 service.

Connecting to OAuth 2.0

Download the library

The first thing you will want to do is to get the latest version of the Leeloo library.  It has moved to the Apache Amber project, so this link might change, but for now I found the ready to download binaries here.

Configure build path

Once you have the library downloaded you’ll want to add the following jars to your build path:

  • jettison-1.2.jar
  • oauth2-client.jar
  • oauth2-common-0.1.jar
  • slf4j-api.1.6.1.jar

Make initial request for authorization

Make sure you already have a unique client id created with the service you are going to access.  Most services out there like Twitter have a page where you can request one for your application.

Once you have this, you will use this to create a url that you will redirect the user of your application to.

In the code snippet below, I am creating the url and then creating a new Intent in Android that will open a web browser at that url.

OAuthClientRequest request = null;
request = OAuthClientRequest
       .authorizationLocation(authenticationUrl)
	   .setClientId("<your client id>").setRedirectURI("<your redirect url>")
		.buildQueryMessage();

Intent intent = new Intent(Intent.ACTION_VIEW,
        Uri.parse(request.getLocationUri() + "&response_type=code"));
startActivity(intent);

A couple of things to note about this code snippet:

  • You’ll need to replace client id with your client id and redirect URI with your redirect URI.
  • The redirect URI for an Android application is going to be some protocol that doesn’t really exist, but you can tell your application to respond to.  (We’ll cover that in the next step, but you might have some URI like myapp://oauthresponse)
  • I had to add a “&response_type=code” to the end of my URL because the authentication service required it.  You might have to look and see how the service you are trying to access expects requests to be formed.

Configure your application to respond to your unique URI

In the previous step we had set the redirect to a unique URI like “myapp://oauthresponse”, now you will need to configure the activity you want to handle the response from the service to intercept that protocol.

You can do this by adding an intent filter to that activity like so:

<intent-filter>
	<action android:name="android.intent.action.VIEW"/>
	<category android:name="android.intent.category.DEFAULT" />
	<category android:name="android.intent.category.BROWSABLE"/>
	<data android:scheme="myapp" android:host="oauthresponse"/>
</intent-filter>

With this intent filter we are telling our activity to respond to a URI request in the form of “myapp://oauthresponse”.

Configure your activity to respond to handle the intent you registered to receive

Next we’ll want to set up an override in our activity to handle the new intent that will be called on our activity.  We can then pull the code the service gave us out and use that to request a real token.

@Override
protected void onNewIntent(Intent intent)
{
	Uri uri = intent.getData();

   if (uri != null && uri.toString()
           .startsWith("myapp://oauthresponse"))
	{
        String code = uri.getQueryParameter("code");
        // ...
   }
}

This code will allow us to respond to the intent that will be fired by the web browser when the service redirects the user to “myapp://oauthresponse.”

Exchange the code for a token

Next we need to get a real token instead of a code.  When the user typed in their username and password and granted access to our application, the server called our callback URI with a code that we extracted in the last step.

Now we can pass that code back up to the server along with our client secret and client id and get an access token.

OAuthClientRequest request = null;

request = OAuthClientRequest.tokenLocation("<service request URL>")
	.setGrantType(GrantType.AUTHORIZATION_CODE)
   .setClientId("<your client id>")
	.setClientSecret("<your client secret>")
	.setRedirectURI("myapp://oauthresponse")
	.setCode(code)
	.buildBodyMessage();

OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

OAuthJSONAccessTokenResponse response = oAuthClient.accessToken(request);
String token = response.getAccessToken();

In this bit of code we are sending back to the server all the information we have that identifies our application as well as the code that proves the user allowed us to access that service.

Then we get back an access token from the server.  I would recommend you save this access token so that you don’t have to do this reauthentication in the future.

Wrapping it up

So what we have been able to do here is to redirect a user to the right page to authenticate our application, and then wire up our activity to respond to the redirect the service gives us in order to ultimately get an access token we can use to prove we are authorized to access that service on behalf of the user.

Be cautious though, because not everyone is implementing OAuth 2.0 exactly the same way, since the spec is not finalized.  So you might run into issues where things aren’t working exactly as laid out in this post.  If that is the case, you may have to modify a URL that is generated or something along those lines.

In my next post, I’ll show you what you can actually do with your authorization token.  We’ll go through calling a REST based API web service from Android.

Feel free to post any questions in comments.  I used this code to connect to the Dailymile.com API in my PaceMaker application.

As always, you can subscribe to this RSS feed to follow my posts on Making the Complex Simple.  Feel free to check out ElegantCode.com where I post about the topic of writing elegant code about once a week.  Also, you can follow me on twitter here.