Sunday, February 7, 2010

Accessing a security-enabled Google App Engine service with Apache Camel

In a previous post I've described the low-level details for programmatic login to a Google App Engine service from a Java client. Things are getting much easier when using Apache Camel. The recently committed glogin component makes it trivial to login to a remotely deployed Google App Engine service as well as to a local development server. In the following example, an application-specific authorization cookie is obtained with the glogin component. It authorizes a client application to access http://camelcloud.appspot.com on Google App Engine.

import org.apache.camel.Exchange;
import org.apache.camel.ProducerTemplate;
import static org.apache.camel.component.gae.login.GLoginBinding.*;

...

ProducerTemplate template = ...

Exchange result = template.request(
"glogin://camelcloud.appspot.com"
+ "?userName=replaceme@gmail.com"
+ "&password=replaceme", null);
String cookie = result.getOut().getHeader(
GLOGIN_COOKIE, String.class));

Please note that the password is only sent to the Google Accounts API for authentication. It is never sent to Google App Engine or included into any URL. The obtained authorization cookie is valid for 24 hours and needs to be sent with subsequent requests to the GAE application. If inclusion of user credentials in an endpoint URI is not an option, username and password can also be dynamically set (per request) using Camel message headers:

import org.apache.camel.Exchange;
import org.apache.camel.ProducerTemplate;
import static org.apache.camel.component.gae.login.GLoginBinding.*;

...

ProducerTemplate template = ...

Exchange result = template.request(
"glogin://camelcloud.appspot.com", new Processor() {
public void process(Exchange exchange) {
exchange.getIn().setHeader(
GLOGIN_USER_NAME, "replaceme@gmail.com");
exchange.getIn().setHeader(
GLOGIN_PASSWORD, "replaceme");
}
});
String cookie = result.getOut().getHeader(
GLOGIN_COOKIE, String.class));

To login to a local development server, the devMode parameter in the endpoint URI must be set to true.

import org.apache.camel.Exchange;
import org.apache.camel.ProducerTemplate;
import static org.apache.camel.component.gae.login.GLoginBinding.*;

...

ProducerTemplate template = ...

Exchange result = template.request(
"glogin://localhost:8888"
+ "?userName=test@example.org"
+ "&devMode=true", null);
String cookie = result.getOut().getHeader(
GLOGIN_COOKIE, String.class));
The glogin component is part of the Camel Components for Google App Engine.

4 comments:

  1. Hey Martin,

    great blogs about Camel and GAE.

    I am just starting with GAE. Thus, I wonder if you have a fully working example which can be downloaded as it is available for the GAE cloud weather application?

    I see that you use the glogin component to authorize to the GAE app. But how do you send a request afterwards to the app (a request for a weather report in your case). Do you have to send a request to a GAE service using one of the other Camel components such as the URL fetch service?

    Thank you for help...


    Best regards,
    Kai Wähner (Twitter: @KaiWaehner)

    ReplyDelete
  2. Hi Kai,

    unfortunately, I never included such an example in the official Camel examples but I found a local Scala example on my laptop how to do that (shouldn't be a big deal to do something similar in Java with any HTTP client lib). Hope that helps.

    Cheers,
    Martin

    ReplyDelete
  3. Thank you Martin,

    Actually, I prefer Scala because I wanna do some more Scala coding combined with Cloud apps, Camel and Akka in the next months.

    I will "convert" your HTTP example to some Scala Camel code (should be very easy) and use it...


    Best regards,
    Kai Wähner (Twitter: @KaiWaehner)

    ReplyDelete
  4. Sounds good! Maybe you also want to take a look at scalaz-camel if you want to use Camel within Scala apps.

    ReplyDelete