Android Client-side OAUTH

OAUTH is a system for allowing users to manage third-party access to protected resources on a trusted provider. The OAUTH provider in this case is a Ruby on Rails web application that records location data. The "third-party" is an Android mobile application playing the role of the OAUTH consumer. The cell phone owner is the user that gives permission to the provider to allow the third party, here after called the consumer, to access protected resources.

Android Client-side OAUTH

Step 0: Add the OAUTH java library to your android app

Add the jar file from the Java OAUTH project to the lib directory in your android application. Then editing the properties of the project in Eclipse to add a jar file to the classpath.

typo:code $ cd ANDROID_PROJECT $ mkdir lib; cd lib $ svn export http://oauth.googlecode.com/svn/code/maven/net/oauth/oauth-core/20090121/oauth-core-20090121.jar /typo:code

Step 1: Acquire a consumer token

A consumer token consists of a key and secret and identifies the consumer software to the provider. Acquiring this token is beyond the scope of OAUTH and each provider does it differently. The simplest implementation is to create one token that all consumer software uses. It means the provider will not be able to differentiate between different consumer software but in this case, the android app is the only consumer. The value of the token can be put in the OAUTH discovery document.

If you are using someone else's OAUTH service, you'll have to go through their steps for getting a consumer token. The token remains the same for the life of the software.

String consumerKey = "icecondor-nest-"+ICECONDOR_VERSION; String consumerSecret = ""; /typo:code

Step 2: Acquire a request token

A request token is a unique concept in OAUTH. You have to ask permission to ask for permission. The provider will have a URL for acquiring a request token. You have to hard code this or use OAUTH discovery to find this URL.

public static OAuthServiceProvider defaultProvider() { (... load oauth request/authorization/access URLs) OAuthServiceProvider provider = new OAuthServiceProvider( request_url, authorization_url, access_url); return provider; }

public OAuthAccessor defaultAccessor() { String callbackUrl = "icecondor-android-app:///"; OAuthServiceProvider provider = defaultProvider(); OAuthConsumer consumer = new OAuthConsumer(callbackUrl, consumerKey, consumerSecret, provider); OAuthAccessor accessor = new OAuthAccessor(consumer); return accessor; }

/typo:code

Step 3: Have the user authorize the request token

Use the authorization URL to send the user to the provider's website via a web browser, along with the request token and a callback URL. The user then informs the provider that the request is approved.

OAuthAccessor client = defaultAccessor(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData( Uri.parse( client.consumer.serviceProvider.userAuthorizationURL+ "?oauth_token="+client.requestToken+ "&oauth_callback="+client.consumer.callbackURL)); startActivity(i); /typo:code

Step 4: The user returns to the android app

Once the user has granted permission to the request token, the provider's web site will send the user back to the android app using the callback url. Android apps can register a "protocol" that can be used when constructing URLs on web pages. The android browser will handle URLs with a registered protocol and redirect the user to that android application. I choose the protocol of "icecondor-android-app" which makes a url that looks like "icecondor-android-app:///". To register a protocol in your android app, add an extra block to the AndroidManifest.xml.

/typo:code

Step 5: Extract the request token

The callback URL is modified to contain the request token. Its the same request token that was sent to the provider's web site, but since the app has restarted, its easier to use the token in the URL than to remember it locally. At the startup of the android app, use the Intent that caused the application to launch - it will contain extra data. The extra data is the URL the provider generated to return the user to the app.

public void onResume() { // extract the OAUTH access token if it exists Uri uri = this.getIntent().getData(); if(uri != null) { String blessed_request_token = uri.getQueryParameter("oauth_token"); String blessed_request_secret = uri.getQueryParameter("oauth_token_secret"); // See step 6 } }
/typo:code

Step 6: Convert the request token to an access token

The access token will allow us to make requests to the service provider.

access_token = convertToAccessTokenAndSecret( blessed_request_token, blessed_request_secret); setDefaultAccessToken(access_token[0]); setDefaultAccessSecret(access_token[1]);

public static String[] convertToAccessTokenAndSecret( String request_token, String request_secret) { ArrayList> params = new ArrayList>(); OAuthClient oclient = new OAuthClient(new HttpClient4()); OAuthAccessor accessor = defaultAccessor(); accessor.accessToken = request_token; accessor.tokenSecret = request_secret; try { OAuthMessage omessage = oclient.invoke(accessor, "POST", accessor.consumer.serviceProvider.accessTokenURL, params); return new String[] {omessage.getParameter("oauth_token"), omessage.getParameter("oauth_token_secret")};

} ... } /typo:code

Step 7: Access the protected resource

This step is very similar to step 6. The access token is used instead of the request token.

ArrayList> params = new ArrayList>(); addPostParameters(params, your_application_data); OAuthClient oclient = new OAuthClient(new HttpClient4()); OAuthAccessor accessor = defaultAccessor(); accessor.accessToken = getDefaultAccessToken(); accessor.tokenSecret = getDefaultAccessSecret(); OAuthMessage omessage = oclient.invoke(accessor, "POST", access_url, params); /typo:code

Much thanks goes to Sean Sullivan who trailblazed the OAUTH on Android process with the jFireeagle android app, and gave me help and advice in my own project.

tags: