FaceBook authentication using Java

Bookmark/Share » Post FaceBook authentication using Java to digg. bookmark on del.cio.us Add TheLiveWeb.net to Technorati. add to stumbleupon Post FaceBook authentication using Java to Reddit Google Bookmark

Faecbook Looking around on the web, it seems the biggest hurdle that people face while writing a Facebook application in java is getting the authentication piece to work. There are some blogs where the solutions have been posted, and that would work. However, I noticed that they recommend using login servlet url as the callback url so that all the requests pass through that servlet before your custom logic routes the requests to the desired servlet based on url. That would sure work, but it looks like a hack (or at least not elegant)! More so, because servlet spec already comes with something that helps us intercept all the requests. Yes, I am talking about Servlet Filters which really makes it clean, and easy.

You can configure a servlet filter that intercepts all the requests, makes sure that user is logged in (or else redirects user to login page) before letting the request flow to your servlet that will serve this request. The application code can rest assured that the user has logged in, or else the request won’t reach it!

I spent some time writing the servlet filter and the authentication class which I thought would make sense to share. You can download the source code using the link at the end of this post. Here is a brief description of how it works.

The doFilter method of FaceBookAuthFilter simply delegates authentication verification to FaceBookAuthHandler class and accordingly let’s the user in, or redirects to login page:

public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
    HttpServletRequest httpReq =
            (HttpServletRequest) request;
    HttpServletResponse httpRes =
            (HttpServletResponse) response;
    try {
      FacebookRestClient authClient =
      FaceBookAuthHandler.getAuthenticatedClient(
                 httpReq, _apiKey, _secretKey);
      request.setAttribute(
                 "auth.client", authClient);
      chain.doFilter(request, response);
    } catch (FailedLoginException fle) {       

    //user not logged in
    forceLogin(httpRes);
} catch (Exception e) {
//handle exception
}       

}

Once the request reaches the application (which implies user is already logged in), you can just get the FaceBookRestClient from request object and use it as follows:

FaceBookRestClient client=(FaceBookRestClient)
       request.getAttribute("auth.client");
client.friends_get();//and so on

In order to configure the filter, you’d need to add the following to the web.xml

<web-app>
<display-name>
  Facebook Application
</display-name>
<filter>       

<filter-name>
 FaceBookAuthFilter
</filter-name>       

<filter-class>
 net.theliveweb.facebook.FaceBookAuthFilter
</filter-class>       

<init-param>
  <param-name>api_key</param-name>
  <param-value>[api-key]</param-value>
</init-param>
<init-param>
  <param-name>secret_key</param-name>
  <param-value>[secret-key]</param-value>
</init-param>
</filter>
<filter-mapping>
  <filter-name>FaceBookAuthFilter</filter-name>
  <url-pattern>*.do</url-pattern>
</filter-mapping>       

</web-app>

You will need to make the following changes to the web.xml:

  • Replace the api-key and secret-key
  • Change the url-pattern from *.do to the one that you use in your app

And you should be all set!

Following are the two classes that you can download:

  • FaceBookAuthFilter : The http servlet filter for intercepting user requests
  • FaceBookAuthHandler : Class used to verify authentication. Can also be used stand alone.

You can download the source code here.

[Click here for the basics of Facebook development platform, and how to get a simple application working]

If you liked this post or find this website useful, please consider subscribing to the full feed RSS. You can also subscribe by Email and have new posts sent directly to you.
Share » Post FaceBook authentication using Java to digg. bookmark on del.cio.us Add TheLiveWeb.net to Technorati. add to stumbleupon Post FaceBook authentication using Java to Reddit Google Bookmark

Next Steps »

11 Responses to “FaceBook authentication using Java”

  1. […] [Update: If you’re writing the app in java, check this out] […]

  2. i found an error in your source code…. before returning the client you are asking for a session id using

    fbClient.auth_getSession(authToken);

    you are not using it at all… also you haven’t checked if authToken is null , if it is it throws a null pointer exception…

    by the way thanks for the code… really clean job…

  3. Thanks Juan. The code checks for authToken not being null :

    if (sessionKey != null) {
    	...
    } else  if (authToken != null) {
    	...
    } else {
    	throw new FailedLoginException(...);
    }
    

    if neither sessionKey nor authToken are found, it throws FailedLoginException which the caller should catch and send the user to login page. Which line in the code threw NullPointerException? Let me know if you’re still getting the error so that I can fix it if needed. Thanks.

  4. Juan is referring to line 29 in FaceBookAuthHandler.java
    You invoke fbClient.auth_getSession(authToken) without checking if authToken is null (it can be) and regardless of the sessionKey being already provided. You also don’t do anything with the returned value.
    Still, great post, Java documentation on the Facebook API is very lacking and I personally thank you for trying to fill the gaps.

  5. Thanks Javier. It should be fixed now - that line was anyway redundant since the session key is obtained from the request parameter.

  6. Great post !

    However, I’ve got a few newbie questions :

    - it looks like the filter instanciates a new client upon each request, but when your application has multiple “configuration” pages in canvas, each one being called from a link like edit.jsp,delete.jsp, etc. , couldn’t a client be instead stored in a request.getSession() and retrieved later on ? I fear multiple clients creation could be cpu consuming.

    - maybe you could commit this filter code to http://code.google.com/p/facebook-java-api/ , with a new web.xml init param defining which type of client is to be created, REST, JSON or JAXB ? (disclaimer: I’m not the project owner)

    - there is a really minor “typo” in your web.xml, needs a breakline to indent nicely (yes, I’m nitpicking :D)

  7. Thanks Laurent for the comments. Your suggestions are completely valid - the reason I didn’t show storing the facebook client in http session was that in this post I wanted to mainly emphasize on use of filter to do the authentication and keep it simple. Once you have this working, you can add the code to cache facebook client in session. Or if people want it, I can add that part to the sample code.

    I am also thinking of posting an example using the facebook api on code.google.com when time permits.

    Thanks again for suggestions!

  8. Thanks for the helpful information. I noticed a couple of things and was curious if you noticed similar behavior.

    One, I noticed that an earlier post had mentioned removing the following piece of code:

    fbClient.auth_getSession(authToken);

    However, it was my experience that this was necessary because with this code removed, I would get errors returned from FaceBook stating that the session was no longer valid. I would agree, that this doesn’t really make sense, but that was my observation.

    Second, I tried save the ‘auth client’ in the HttpSession instead of the Request and was unsuccessful. When looking at the stack trace it would appear there was some sort of ‘null pointer exception’ that was eventually described as a jasper exception. Unfortunately, I couldn’t get much more information and eventually abandoned trying to store this in the session … which would of course be much more efficient.

    If you have noticed the similar behavior these observations, I would be interested.

  9. Thanks Darin. I think the “session not valid” problem you referred to may occur when someone tries to access the app before logging into facebook. So I have added that line of code, but it gets executed only if authToken is not null so the NPE reported earlier does not occur.

  10. ok, sorry it took some time to get back with you.

    I’m embarrassed to say the problem was really on my side and some configuration issues. My Tomcat instance is running behind an Apache web server and I forgot to include ‘QSA’ on my rewrite rules when forwarding the requests to my Facebook application. This was then complicated by the fact that my JSP pages (at least the underlying .java files) were not being rebuilt when I was making changes to the JSP pages. But, I’ve now fixed these problems and can report that everything is working nicely … even when setting the auth variable as a session variable as opposed to a request variable.

    Thanks again for your contribution as this really helped clarify how one could perform Facebook authentication within a Java (J2EE) environment.

  11. Thanks Darin for posting back your findings. Great to know that it worked for you!

Leave a Reply

Related Posts from the Past: