Friday, January 2, 2009

Google Apps 2-Legged OAuth in Java

The java library of gdata v1.24 doesn’t support the use of 2-legged OAuth yet. If you try to implement the 2-legged OAuth with this library, it will throw you the exception below even you’ve done everything correctly:
com.google.gdata.client.authn.oauth.OAuthException: oauth_token does not exist.
The temporary solution to this problem is to change the source code inside the gdata library. Only two files need to be modified to makes the 2-legged OAuth working.

OAuthHelper.java

Inside this class, find getAuthorizationHeader method and comment out the following line:
oauthParameters.assertOAuthTokenExists();

GoogleAuthTokenFactory.java

Inside this class, find setOAuthCredentials method and comment out the following line:
parameters.assertOAuthTokenExists();

Recompile your gdata source code and you should be able to get the 2-legged OAuth works.

Below is the snippet code of 2-legged OAuth example.

import java.io.IOException;
import java.net.URL;

import com.google.gdata.client.authn.oauth.GoogleOAuthParameters;
import com.google.gdata.client.authn.oauth.OAuthException;
import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer;
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.util.ServiceException;

public class OAuthManager {

public static void main(String [] args) throws IOException, ServiceException
{
try {
//Setting 2-legged OAuth credentials
GoogleOAuthParameters oauthParam = new GoogleOAuthParameters();
oauthParam.setOAuthConsumerKey("domain.com");
oauthParam.setOAuthConsumerSecret("yourdomainconsumersecret");
oauthParam.setScope("http://www.google.com/m8/feeds/");
URL feedUrl = new URL("http://www.google.com/m8/feeds/contacts/default/full/?xoauth_requestor_id=email@domain.com");

ContactsService contactsService = new ContactsService("apps-name");
contactsService.setOAuthCredentials(oauthParam, new OAuthHmacSha1Signer());

//Making request to Google
ContactFeed resultFeed = contactsService.getFeed(feedUrl, ContactFeed.class);

System.out.println("Response Data:");
System.out.println("Title: " + resultFeed.getTitle().getPlainText());

System.out.println("Showing " + resultFeed.getEntries().size() + " contact(s).");
for(int i = 0; i < resultFeed.getEntries().size(); i++)
{
ContactEntry entry = resultFeed.getEntries().get(i);
System.out.println((i + 1) + ". " + entry.getTitle().getPlainText());
}
} catch (OAuthException e) {
e.printStackTrace();
}
}
}