Android Client-side OAUTH

Android Client-side OAUTH

OAUTH is a system for allowing users to manage third-party access to their resources on a given provider. The project that I am working on is a Ruby on Rails web app, being the OAUTH provider, and an Android client app, being the OAUTH consumer. The cell phone owner is the OAUTH user that gives permission to the provider to allow 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.

$ 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
Step 1: Acquire a consumer token

A consumer token establishes a relationship between the consumer and the provider, irregardless of the user. Acquiring this token is beyond the scope of OAUTH. Each provider does it differently. The simplest way to establish this relationship is to create one token that all consumers use. It means the users will not be able to differentiate between consumers but in my case, the android client is the only consumer (for now). With a static token, the value of the token can be put in the OAUTH discovery document. I took a shortcut here and hardcoded a consumer token into the source.

String consumerKey = "icecondor-nest-"+ICECONDOR_VERSION;
String consumerSecret = "";
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 an access token. You have to hard code this or use OAUTH discovery to find this URL. I hardcoded the URL into the code, which populates a sqlite database. In the future, the user will be able to define any number of service providers.

OAuthServiceProvider defaultProvider() {
    // pull these URLs from the local database of providers, with icecondor being the default
    new OAuthServiceProvider(request_url, authorization_url, access_url);
}

OAuthAccessor defaultClient() {
    String callbackUrl = "icecondor-android-app:///";
    OAuthServiceProvider provider =  defaultProvider(ctx);
    OAuthConsumer consumer = new OAuthConsumer(callbackUrl, consumerKey,
                                    consumerSecret, provider);
    OAuthAccessor accessor = new OAuthAccessor(consumer);
    OAuthClient client = new OAuthClient(new HttpClient4());
}

Step 3: Have the user authorize the request token

Use the authorization URL to send the user to a web browser, along with the request token and a callback URL so that the web site can send the user back into the android application.

OAuthAccessor client = defaultClient();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(client.consumer.serviceProvider.userAuthorizationURL+
                                  "?oauth_token="+client.requestToken+
                                  "&oauth_callback="+client.consumer.callbackURL));
startActivity(i);
Step 4: The consumer web site returns to the android app

Once the user has granted permission to the request token, the consumer'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 registered protocols 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.

<manifest>
 <application>
   <activity>
           <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="icecondor-android-app"/>
            </intent-filter>
   </activity>
 </application>
</manifest>
Step 5: Extract the request token

The callback URL is modified to contain the access token. This is the part we want to save. Its the same token that was sent to the web site, but since the app has restarted, its easier to use the token in the URL than to remember it locally. The place to extract the access token is in the startup of the android app - the intent that caused the application to start will contain extra data. The extra data is the original URL that caused the web browser to launch the android app.

public void onResume() {
    // extract the OAUTH access token if it exists
    Uri uri = this.getIntent().getData();
    if(uri != null) {
      String access_token = uri.getQueryParameter("oauth_token");
        // See step 6
    }
}  
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 = convertToAccessToken(blessed_request_token);
    setDefaultAccessToken(access_token, this); // keep this in the database

    public static String convertToAccessToken(String request_token, Context ctx) {
  ArrayList<Map.Entry<String, String>> params = new ArrayList<Map.Entry<String, String>>();
  OAuthClient oclient = new OAuthClient(new HttpClient4());
  OAuthAccessor accessor = LocationRepositoriesSqlite.defaultAccessor(ctx);
  params.add(new OAuth.Parameter("oauth_token", request_token));
  try {
    OAuthMessage omessage = oclient.invoke(accessor, "POST",  
                                       accessor.consumer.serviceProvider.accessTokenURL, params);
    return omessage.getParameter("oauth_token");
       } ...
    }
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<Map.Entry<String, String>> params = new ArrayList<Map.Entry<String, String>>();
    addPostParameters(params, fix); // put the application data into the HTTP post
    OAuthClient oclient = new OAuthClient(new HttpClient4());
    OAuthAccessor accessor = LocationRepositoriesSqlite.defaultAccessor(this);
    params.add(new OAuth.Parameter("oauth_token", LocationRepositoriesSqlite.getDefaultAccessToken(this)));
    OAuthMessage omessage = oclient.invoke(accessor, "POST",  ICECONDOR_READ_URL, params);

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.

Article From: http://is00hcw.spaces.live.com/blog/cns!30EBEBD8BCD440DC!683.entry

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值