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 theJava OAUTH projectto 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 theOAUTH 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 toSean Sullivanwho trailblazed the OAUTH on Android process with thejFireeagleandroid app, and gave me help and advice in my own project.

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

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. Android studio finished with non-zero
  2. Edittext输入框限制字母数字
  3. Android开发之Java集合类性能分析
  4. Android下多页显示技巧
  5. android用sharepreference保存输入框中的
  6. Android一键锁屏开发全过程【源码】【附
  7. android backgroud alpha
  8. 2010.12.26——— android 获得手机号码
  9. Android加速度传感器数值的过滤
  10. Android 之 setTextColor 写法