Skip to content

Instantly share code, notes, and snippets.

@DomDerrien
Created June 6, 2011 01:44
Show Gist options
  • Save DomDerrien/1009626 to your computer and use it in GitHub Desktop.
Save DomDerrien/1009626 to your computer and use it in GitHub Desktop.
OAuth authentication handling in a Android application
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="twetailer.console"
android:versionName="0.1" android:versionCode="1">
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application android:label="@string/app_name" android:icon="@drawable/ase_men">
<activity android:name=".Dashboard"
android:label="@string/app_name" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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="ase" android:host="oauthresponse"/>
</intent-filter>
</activity>
<activity android:name="Preferences" android:label="@string/pref_name">
</activity>
</application>
</manifest>
package twetailer.console;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;
import twetailer.oauth.OAuthDefs;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.Toast;
public class Dashboard extends Activity {
private static CommonsHttpOAuthConsumer consumer = null;
private static CommonsHttpOAuthProvider provider = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Preferences.setPreferenceContext(PreferenceManager.getDefaultSharedPreferences(getBaseContext()));
boolean justAuthenticated = checkOAuthReturn(getIntent());
if (!justAuthenticated && Preferences.get(Preferences.OAUTH_KEY, "").length() == 0) {
// Display the pane with the warning message and the sign in button
setContentView(R.layout.main_noauth);
// Update the 'Remember me' checkbox with its last saved state, or the default one
final String saveOAuthKeysPrefs = Preferences.get(Preferences.SAVE_OAUTH_KEYS, Preferences.SAVE_OAUTH_KEYS_DEFAULT);
((CheckBox) findViewById(R.id.app_noauth_keepmeconnected)).setChecked(Preferences.SAVE_OAUTH_KEYS_YES.equals(saveOAuthKeysPrefs));
// Attach the event handler that will initiate the authorization process up to opening the browser with the authorization page
findViewById(R.id.app_noauth_continue).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Check if the 'Keep me connected' check box state changed and save its new state
boolean keepMeConnected = ((CheckBox) findViewById(R.id.app_noauth_keepmeconnected)).isChecked();
if (Preferences.SAVE_OAUTH_KEYS_YES.equals(saveOAuthKeysPrefs) != keepMeConnected) {
Preferences.set(Preferences.SAVE_OAUTH_KEYS, keepMeConnected ? Preferences.SAVE_OAUTH_KEYS_YES : Preferences.SAVE_OAUTH_KEYS_NO);
}
// Set up the OAuth library
consumer = new CommonsHttpOAuthConsumer("<your_app_public_key>", "<your_app_secret_key>");
provider = new CommonsHttpOAuthProvider(
"https://<your_app_id>.appspot.com/_ah/OAuthGetRequestToken",
"https://<your_app_id>.appspot.com/_ah/OAuthAuthorizeToken",
"https://<your_app_id>.appspot.com/_ah/OAuthGetAccessToken");
try {
// Steps 1 & 2:
// Get a request token from the application and prepare the URL for the authorization service
// Note: the response is going to be handled by the application <intent/> registered for that custom return URL
String requestTokenUrl = provider.retrieveRequestToken(consumer, "ase://oauthresponse");
// Step 3:
// Invoke a browser intent where the user will be able to log in
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(requestTokenUrl)));
}
catch(Exception ex) {
Toast.makeText(Dashboard.this, R.string.app_noauth_requesttoken_ex, Toast.LENGTH_LONG).show();
Log.e("Dashboard no auth", "Cannot initiate communication to get the request token\nException: " + ex.getClass().getName() + "\nMessage: " + ex.getMessage());
}
}
});
}
else {
setContentView(R.layout.main);
}
}
@Override
protected void onNewIntent(Intent intent) {
checkOAuthReturn(intent);
}
private boolean checkOAuthReturn(Intent intent) {
boolean returnFromAuth = false;
Uri uri = intent.getData();
if (uri != null && uri.toString().startsWith("ase://oauthresponse")) {
// Step 4:
// Get the request token from the Authentication log in page
String code = uri.getQueryParameter("oauth_verifier");
try {
// Step 5:
// Get directly the access tokens
provider.retrieveAccessToken(consumer, code);
Log.e("Dashboard no auth", "User authenticated");
returnFromAuth = true;
// Persist the tokens
if (Preferences.SAVE_OAUTH_KEYS_YES.equals(Preferences.get(Preferences.SAVE_OAUTH_KEYS, Preferences.SAVE_OAUTH_KEYS_DEFAULT))) {
Preferences.set(Preferences.OAUTH_KEY, consumer.getToken());
Preferences.set(Preferences.OAUTH_SECRET, consumer.getTokenSecret());
Log.e("Dashboard no auth", "User tokens persisted as preferences");
}
}
catch(Exception ex) {
Toast.makeText(Dashboard.this, R.string.app_noauth_accesstoken_ex, Toast.LENGTH_LONG).show();
Log.e("Dashboard no auth", "Cannot complete communication to get the request token\nException: " + ex.getClass().getName() + "\nMessage: " + ex.getMessage());
}
}
return returnFromAuth;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ase_network"
android:layout_margin="5dip"
android:layout_gravity="top"
></ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_noauth_warning"
android:layout_marginRight="5dip"
android:layout_marginTop="5dip"
android:layout_marginBottom="5dip"
></TextView>
</LinearLayout>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/app_noauth_keepmeconnected"
android:layout_gravity="center_horizontal"
android:id="@+id/app_noauth_keepmeconnected"
></CheckBox>
<Button
android:text="@string/btn_continue"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/app_noauth_continue"
android:layout_gravity="center_horizontal"
></Button>
</LinearLayout>
package twetailer.console;
import android.content.SharedPreferences;
import android.preference.PreferenceActivity;
import android.util.Log;
public class Preferences extends PreferenceActivity {
protected static SharedPreferences appPrefs;
protected static final String OAUTH_KEY = "oauthKey";
protected static final String OAUTH_SECRET = "oauthSecret";
protected static final String SAVE_OAUTH_KEYS = "saveOAuthKeys";
protected static final String SAVE_OAUTH_KEYS_YES = "Y";
protected static final String SAVE_OAUTH_KEYS_NO = "N";
protected static final String SAVE_OAUTH_KEYS_DEFAULT = SAVE_OAUTH_KEYS_NO;
protected static void setPreferenceContext(SharedPreferences preferences) {
appPrefs = preferences;
}
protected static String get(String key, String defaultValue) {
try {
return appPrefs.getString(key, defaultValue);
}
catch(Exception ex) {
return set(key, defaultValue);
}
}
public static String set(String key, String value) {
SharedPreferences.Editor editor = appPrefs.edit();
editor.putString(key, value);
editor.commit();
return value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment