Securing Your Play 2.1.1 Web Application Using a Filter

After deploying my Play 2.1.1 based application to Cloudbees, I had the problem that everyone could access it. Not very ideal if you want to restrict your program to only a single audience.

To solve the problem you would usually write a complicated user-based authentication system. Slightly an overkill, if you don’t need different users accessing your program at all. My idea was more that the user has to add an URL parameter with a secret key, the first time the application is called. For later requests the key would just be stored in the session object.

That way you basically access the program via the following URL:
http://myapp.cloudbees.net/?access_key=secret
instead of just using:
http://myapp.cloudbees.net

The solution is quite simple. You just have to add a Filter that is checking every request. If the desired URL parameter is passed the request will be processed as usual. If not, we just log the potential threat and return a 404 (IMHO way better than returning a 401 and motivate the intruder that way to hack your site).
Let’s have a look at the following object called AuthFilter:

Don’t blame me if the code above is not ideal – it’s not only my first program using Play but also using Scala.

To activate the filter, you have to enhance the Global object (store it in the default package):

import play.api.mvc.WithFilters
import util.AuthFilter
 
object Global extends WithFilters(AuthFilter)

You may wonder about the method validSession in the AuthFilter. It’s purpose is to add a valid token in your unit tests. Here’s an example with a FakeRequest to /:

route(FakeRequest(GET, "/").withSession(AuthFilter.validSession)).get

Have fun hiding your applications! Don’t forget that the secret key is transferred unencrypted. So if you need some extra security, add SSL. Unfortunately this cost something on Cloudbees….

How to use JSF 2.2 with JBoss 7.1

As the new JSF 2.2 is nearly finished, we all want to play with the new features of it.

Markus Eisele has shown in his blog post Testdriving Mojarra 2.2.0-m08 how to do this with Glassfish 3. He’s German too, I begin to wonder if only we guys are that curious or no one else is using JSF any more ;)

Unfortunately with JBoss 7 we face the same problem he had: We can not just add the new libraries to our WAR archive as they will clash with the JSF 2.1 version of Mojarra (the reference implementation of JSF) already provided by JBoss 7.
So basically we have to disable this old version and activate the new version directly in the application server.

I will show you how to do it with JBoss 7.1.1 and the M08 release of Mojarra 2.2, but it should work for other versions the very same way:

JSF is divided into two parts: The implementation and the API.

We firstly exchange the former one by starting to download jsf-impl-2.2.0-m08.jar, which is the JAR archive containing the implementation.
After downloading, copy this archive to the folder of the old JSF implementation of your JBoss installation, which will be %JBOSS_HOME%/modules/com/sun/jsf-impl/main in that case.
In the same directory you will find a file called module.xml. Edit it and change the contents of the resources tag like this:

<resources>
    <resource-root path="jsf-impl-2.2.0-m08.jar"/>
</resources>

This is important as it tells JBoss which of the provided JAR archives (now there are two of them) to use. If you want to know more about this: Take a look at JBoss Modules, a module class loading approach JBoss 7 is using.
After that you have finished with exchanging the implementation and basically you have to do the same for the API part:

Firstly download the jsf-api-2.2.0-m08.jar archive and copy it to %JBOSS_HOME%/modules/javax/faces/api/main. Secondly edit the module.xml in the same directory by exchanging the resources tag:

<resources>
    <resource-root path="jsf-api-2.2.0-m08.jar"/>
</resources>

Basically you should be finished now, but there is a bug in the milestone 8 of the API that it has a dependency to the implementation. For that reason you have to declare it by adding the following contents to the dependencies tag of the same module.xml file:

<module name="com.sun.jsf-impl"/>

After that you can restart your modified JBoss instance. As JSF is lazily loaded you have to deploy a WAR referencing JSF to check whether our changes work. If so, you should see a log message like this:

[javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-2) Mojarra 2.2.0-m08

Finally, if you want to use the new features in application, you have to add the following dependency to your pom.xml:

<dependency>
   <groupId>com.sun.faces</groupId>
   <artifactId>jsf-api</artifactId>
   <version>2.2.0-m08</version>
   <scope>provided</scope>
</dependency>

And now have fun using JSF 2.2!

Doing EJB-like transactions with Google App Engine

Using Google App Engine you can’t define a method as transactional with a simple annotation as you can in EJB.
You always need to call some boilerplate code which gets quite annoying.
Therefore the following utility class comes handy, which takes care of the transaction handling for you:

To make use of it, you have to set the same persistence unit as in your persistence.xml configuration file first. Do this by changing the parameter of the method createEntityManagerFactory.

After that you can easily define transcation boundaries like this:

TXUtils.doTransaction(new TXUtils.Transaction<String>() {
    public String doit(EntityManager em) {
	// do something with the EntityManager
    }
});

In this example the transaction method has a return type of String – change this if you need a different one.
The transaction is always starting a new transaction, similar to REQUIRES_NEW in EJB (more about that in the Java EE 6 tutorial). If you want to use another transaction strategy, you will have to modify the code.
It is still not as easy as setting an annotation in EJB, but way better than without. If you want to define transactions for Google App Engine via annotations, you will need some DI engine like Guice or CDI, but then you add a lot of other code that you probably don’t need.

Using the Facebook Graph API from your GWT application

It might happen that you have a GWT application and you want to use the Graph API from Facebook.
As the Graph API requires an authentication with OAuth2 this task can be easily accomplished using the GWT-OAuth2 library.
To simplify things even more I build the following utility class for you:

public class FacebookUtil {
    private String token = null;
 
    private static FacebookUtil instance = new FacebookUtil();
 
    private static final String FACEBOOK_AUTH_URL = "https://www.facebook.com/dialog/oauth";
 
    private static final String FACEBOOK_CLIENT_ID = "MY_CLIENT_ID"; 
 
    private FacebookUtil() {
    }
 
    public static FacebookUtil getInstance() {
	return instance;
    }
 
    public void resetToken() {
	token = null;
    }
 
    private void doAuth(Callback<String, Throwable> callback) {
	final AuthRequest req = new AuthRequest(FACEBOOK_AUTH_URL,
		FACEBOOK_CLIENT_ID).withScopes("email", "user_birthday",
		"user_hometown", "user_location", "publish_stream")
	// Facebook expects a comma-delimited list of scopes
		.withScopeDelimiter(",");
	Auth.get().clearAllTokens();
	Auth.get().login(req, callback);
    }
 
    public void doGraph(final String id,
	    final Callback<JSONObject, Throwable> callback) {
	doGraph(id, RequestBuilder.GET, null, callback);
    }
 
    public void doGraph(final String id, final Method method,
	    final String params, final Callback<JSONObject, Throwable> callback) {
	if (token == null) {
	    doAuth(new Callback<String, Throwable>() {
		public void onSuccess(String token) {
		    FacebookUtil.this.token = token;
		    doGraphNoAuth(id, method, params, callback);
		}
 
		public void onFailure(Throwable reason) {
		    callback.onFailure(reason);
		}
	    });
	} else {
	    doGraphNoAuth(id, method, params, callback);
	}
    }
 
    private void doGraphNoAuth(String id, Method method, String params,
	    final Callback<JSONObject, Throwable> callback) {
	final String requestData = "access_token=" + token
		+ (params != null ? "&" + params : "");
	RequestBuilder builder;
	if (method == RequestBuilder.POST) {
	    builder = new RequestBuilder(method, "https://graph.facebook.com/"
		    + id);
	    builder.setHeader("Content-Type",
		    "application/x-www-form-urlencoded");
	} else if (method == RequestBuilder.GET) {
	    builder = new RequestBuilder(method, "https://graph.facebook.com/"
		    + id + "?" + requestData);
	} else {
	    callback.onFailure(new IOException(
		    "doGraph only supports GET and POST requests"));
	    return;
	}
	try {
	    builder.sendRequest(requestData, new RequestCallback() {
		public void onError(Request request, Throwable exception) {
		    callback.onFailure(exception);
		}
 
		public void onResponseReceived(Request request,
			Response response) {
		    if (Response.SC_OK == response.getStatusCode()) {
			callback.onSuccess(JSONParser.parseStrict(
				response.getText()).isObject());
		    } else if (Response.SC_BAD_REQUEST == response
			    .getStatusCode()) {
			callback.onFailure(new IOException("Error: "
				+ response.getText()));
		    } else {
			callback.onFailure(new IOException(
				"Couldn't retrieve JSON ("
					+ response.getStatusText() + ")"));
		    }
		}
 
	    });
	} catch (RequestException e) {
	    callback.onFailure(e);
	}
    }
 
}

After setting the unique ID of your facebook app in the constant FACEBOOK_CLIENT_ID, you can easily use the Graph API by calling the doGraph method.
Here is an example that posts a message on the feed of the app user by sending some data to the me/feed path:

FacebookUtil.getInstance().doGraph(
	"/me/feed/",
	RequestBuilder.POST,
	"message="
		+ URL.encodeQueryString(message)
		+ "&link=" + URL.encodeQueryString(url),
	new Callback<JSONObject, Throwable>() {
	    public void onFailure(Throwable reason) {
	    }
 
	    public void onSuccess(JSONObject result) {
	    }
	});

As you notice the variables message and url need to be defined with values of your choice before. Now have fun trying other methods of the Graph API.
If you need further permissions, you have to add them as parameters to the call of withScopes inside of the doAuth method.

Using Google App Engine as Backend for Android

If you’re looking for a way to create a backend for your Android application, Google App Engine looks like the perfect choice: You can use Java as you can do for Android and you don’t need to think too much about hosting, as it is all stored in the cloud.

Another benefit is that you can reuse your transfer objects on the client and on server side. But as it is often there are some problems doing this in practice. So you don’t have the same ones I had, I am glad to share my experiences with you.

So first question is what libraries are to use for the client/server communication. At start I tried Restlet 2.0. Looked like a great choice as there are special editions for App Engine and for Android available. In practice it is not very useful as the libraries are to big for Android and I also very much disliked that fully serialized java objects are transfered.

Best approach I found so far is to use Jersey 1.6: It is easy to use and implements the JAX-RS (JSR 311) standard. To set it up on the App Engine, please consult these blog posts from me: Using real POJOs (without JAXB Annotations) as transfer objects with JAX-RS and Storing large images RESTful in the cloud using Google App Engine.

Ok, so far about the server side. To keep things small and simple on the Android side, I mainly created the following wrapper class for the HttpClient to handle the HTTP requests:

This implementation is far from perfect, especially exception handling and passing parameters need to be improved, but it works so far :)

Using this class it is easy to store a file using the FileServerResource from my former blog post. Just call:

File imageFile = new File(new URI(myimgage.getImageURL()));
String url = HttpUtils.getInstance().doPutFile("file/store", imageFile);

Also it is easy to store a transfer object using the doPut method. Note that is is using the ObjectMapper class from Jackson, the same JSON processor that is also used by Jersey.
Jackson is therefore the only additional library that you need on the Android side which keeps the executable small. If you use the same version of Jackson on the client side as on the server side you’re also ensured that the (un-)marshalling process of your transfer objects works flawlessly on both sides.

Hope you liked this approach – feel free to discuss here further ideas.