Friday, December 3, 2010

Authenticated Posts to App Engine Servlets

I thought I would take a moment to further document a Java class I wrote for taking a google account and password and then using it to make an authenticated POST and GET to a servlet hosted on app engine.

The process should be very simple:
1. Create an instance of my GoogleAuthentication.java class with your appspot url and credentials.
2. Use that object to add the auth cookie to your http post and get requests.

The Source code to this class is part of Nimbits4J.jar that allows developers to record time series data to the Nimbits Server running on app engine.  Nimbits is an open source data logger that runs on App Engine - you can learn more about it on www.nimbits.com.

The Source Code to Nimbits4J which contains the client classes is all posted under the GNU license version 3 on Google Code:

http://code.google.com/p/nimbits4j/

It contains a class called GoogleAuthentication.java  that handled getting the token, extracting the cookie information, and so on.

To the code!

With GoogleAuthentication.java or Nimbits4J.jar added to your project, setup these strings


        private final static String gaeAppBaseUrl = "http://appid.appspot.com/";
private final static String gaeAppLoginUrl = gaeAppBaseUrl + "_ah/login";
private final static String googleLoginUrl = "https://www.google.com/accounts/ClientLogin";
private final static String service = "ah"; 


Create the singleton object, passing in the above params, the gmail account and password a very trusting user gave you like this:

        GoogleAuthentication G = GoogleAuthentication.getNewGoogleAuthentication();
        G.ConnectClean(googleLoginUrl, service,  gaeAppBaseUrl,   gaeAppLoginUrl,   email,   password);

In the Nimbits4J project there is also a DataClient.java class which contains methods for talking to the Nimbits Services, but they are simply passing the client object G and the path to the service on app engine, with the params.  The code in red is where the magic happens.  On the Server Side, any calls to:

com.google.appengine.api.users.UserService u = UserServiceFactory.getUserService();

will return a valid user in these requests.


public static String doGet(String serviceUrl, String params, GoogleAuthentication G)
throws IOException {
String retVal = "";


try {
  URL url = new URL(postUrl + "?" + params);  //for example http://appid.appspot.com/service/yourservletmapping?foo=bar


HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("GET");
 
if (G != null)
{
connection.addRequestProperty("Cookie",G.getAuthCookie().getName() + "=" +            G.getAuthCookie().getValue());
}
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
 
String line;


while ((line = reader.readLine()) != null) {
retVal += line;
}
reader.close();


} catch (MalformedURLException e) {
throw e;


} catch (IOException e) {
throw e;
}


return retVal;


}




On the Server Side, your app engine should have your servlets mapped in the web.xml. A good sample of a service running on nimbits is here:

https://code.google.com/p/nimbits-server/source/browse/trunk/NimbitsServer/src/com/nimbits/server/service/CurrentValueService.java







No comments:

Post a Comment