Sunday 31 March 2013

[How To] - Implement Facebook login in JSF using SocialAuth

As a matter of fact, Facebook does not provide an official library for Java developer. To make the matter worse, the provided official Javascript SDK is not very easy to use (at least for me) or to integrate with a JSF application. Luckily, there are several unofficial projects going on at the moment and in my opinon, the best of all should be either RestFB or SocialAuth. Between these two alternatives, I prefer SocialAuth because of 2 reasons. First of all, RestFB doesn't support authentication. In other words, using RestFB, we have to dive into the JavaScript SDK mess to fetch the accessToken from Facebook on our own. Another thing is that SocialAuth supports not only Facebook but also a wide range of other providers such as Google, LinkedIn, etc. So, today, I will use SocialAuth to show you how to implement Facebook login in JSF.

One thing to note is that on SocialAuth's wiki page, there is actually a step-by-step tutorial on connecting to Facebook in a JSF CDI application. I've tried the provided solution but it didn't work out for me. Somehow, I ran into the Unsatisfied dependencies for type [SocialAuth] with qualifiers [@Named] at injection point [[field] error and no one has yet to provide an answer for my question on StackOverflow. So in this post, I will show you another way that I have figured out to connect to Facebook.

In brief, there are 4 steps that you need to follow:
  1. Create an application on Facebook.
  2. Download the latest SocialAuth SDK. In this tutorial, I am using v4.0.
  3. Copy, paste and edit!
  4. Enjoy your achievement :).
Firstly, you need to create an application on Facebook.

From the above page, you need to write down your App ID and App Secret, which would be used to connect to Facebook later. Another thing to note is that the Site URL property needs to be the same as the domain where you deploy your application. So, if you want to test your application locally, simply enter http://localhost:8080/.

After downloading the latest SDK from SocialAuth, which is v4.0 at the moment of this writing, you can proceed to the most interesting part which is coding!

In order to redirect users back to where they have been before logging in, copy and paste this code inside your <f:view>:

After that, copy and paste the following snippet where you want to put your Social login buttons:

One important thing to note is that you should put the login buttons on the top most of your page where no other components can be loaded before these buttons. Otherwise, you may run into java.lang.IllegalStateException when our socialConnect() function attempts to redirect the user if part of the response has been committed. You can also edit the above snippet to add in more buttons for other providers if needed. This is the list of IDs of all providers:

The following is the socialLoginSuccess.xhtml page where users would be redirected to on successful login:

One very important thing to note is that in the above success page, I didn't have the <f:event> component. If your success page uses the same template, which contains the <f:event>, as other pages, you will run into the following exception:

The above exception occurs because the originalURL was wrongly updated to be the authenticationURL. In other words, you will be authenticated one more time.

Finally, this is our @SessionScoped managed bean:

Based on this sample for the file, you should be able to figure out the properties to put in the props easily. In fact, instead of using Java's Properties, there are also several other ways to load the configuration. The complete list includes:

Enjoy your work! :)

Friday 29 March 2013

[How To] - Set up SSL certificate on GlassFish app server

Under your development environment, it may not be very important to have a signed Digital certificate. However, eventually, your application will be accessed by the world. Nowadays, all browsers have a mechanism for alerting users when they enter untrusted environment (i.e. websites with unsigned certificates). Most people will either be scared away or think that your site is not working when they see the following warning page:

So, before serving pages securely, you should configure your app server to use a signed certificate. In case you don't have one yet, entering the following lines into a Terminal should do the job:

One very important thing to note is the -alias s1as portion. You cannot randomly assign a string for this parameter. Normally, GlassFish app server uses s1as as the default Certificate Nickname. To check what your app server is actually using, open the Admin console, under Configurations section, choose server-config, then HTTP Service, then Http Listeners. You will see the Certificate Nickname under the SSL tab on the right.

Next, after creating a digital certificate, you should have it cryptographically signed, which would make it became very difficult for anyone else to forge. For sites involved in e-commerce or any other business transaction in which authentication of identity is important, a certificate can be purchased from a well-known certificate authority such as VeriSign or Thawte.

After that, open your Admin console, under Configurations section, choose server-config, then JVM Settings. Under the JVM Options tab on the right, add the following options:

The next task is to copy the keystore.jks and the cacerts.jks files that you have created earlier into the <GLASSFISH_FOLDER>/glassfish/domains/domain1/config folder.

Lastly, restart your GlassFish app server and you're done! :)

Thursday 28 March 2013

[How To] - Fix javax.mail.NoSuchProviderException: No provider for smtp

At times, you may run into the above Exception even though you're absolutely sure that your sendEmail function is working normally on another project. This Exception happened to me after I updated my project to Use dedicated folder for storing libraries.

The solution in my case was pretty simple.
  1. First, you need to go to Oracle's site to download JavaMail API
  2. After that, add the mail.jar file to your Project's libraries. 
  3. Lastly, right click on your Project, choose Properties, under the Packaging section, you need to check the Package required JARs in EJB jar option.

Hope this helps! :)

[How To] - Change the context root of your EAR project

In your EAR project, normally, you will have a WAR project named yourproject-war, which would also be the context-root of your application if you don't make necessary changes. I have seen many tutorials on the Internet instructing people to update their WAR project's glassfish-web.xml or sun-web.xml file and add the following line:

The above solution will NOT work without deploying the WAR project directly!

What you should do, instead, is to update your EAR project's application.xml file which should be found inside your EAR project's Configuration Files folder in NetBeans.

If the file is not there, simply right-click on your EAR project, choose New and create a Standard Deployment Descriptor.

After opening the application.xml file, the next task is straight-forward.

Good luck! :)

Wednesday 27 March 2013

[How To] - Handle Unicode contents obtained using PrimeFaces

At times, when you try to persist Unicode contents (e.g. Chinese characters), that are obtained using PrimeFaces's components, to the database and read back, you will see tons of question marks on your browser. For a detailed discussion on the root cause of this problem, please refer to the following answer of BalusC on StackOverflow.

To fix this issue, you need to make the following changes:
  • Add these 2 properties to your JDBC connection.
  • Re-configure the server to use UTF-8 instead of ISO-8859-1 as default coding. Using GlassFish, you simply need to add the following line to your project's glassfish-web.xml file:
Note: To have a better understanding of how to properly handle Unicode characters in JSF, please refer to the following article by BalusC: Unicode - How to get the character right?

[How To] - Fix Flash player cover other components

At times, you may run into a situation in which some components of your page get buried under the Flash player as following:

This is a well-known z-index issue caused by the Flash player. In brief, instead of being rendered within the browser, the Flash player is rendered in a new window (a bit like an i-frame) that is put on top of your browser. Because of this weird rendering, the Flash player will always stay on top of other components on your pages.

Luckily, the solution to this problem is pretty simple :). You simply need to set the wmode parameter of the Flash player to opaque.

With JSF and PrimeFaces's p:media component, you can easily achieve the above goal as following:

Tuesday 26 March 2013

[How To] - Make non-secure cookie default for all kinds of connection

In a JavaEE application, JSESSIONID cookies' cookieSecure property can have one of the following values:

- true: All JSESSIONID cookies created by the container on behalf of the web application will be marked as secure.
- false: All JSESSIONID cookies created by the container on behalf of the web application will be marked as non-secure.
- dynamic (default):  A JSESSIONID cookie created by the container on behalf of the web application will inherit its security setting from the request that initiated the correspoding session: If the session was initiated by an HTTPS request, its JSESSIONID cookie will be marked as secure, and will remain non-secure otherwise.

Since the default value is dynamic, if the 1st page a user goes to is a HTTPS page (e.g. Login page), the cookie given to the user will be marked as secure. As a result, in many cases, subsequent non-secure HTTP pages may not be able to use the obtained cookie and thus, the user would be asked to log in one more time.

To overcome this issue, one way is to override the cookieSecure property's default value and change it to false. You can achieve this goal by updating the glassfish-web.xml file to include the following lines:

  1. If cookie settings are defined declaratively in the web.xml file, the cookie properties defined here will take precedence.
  2. If cookie settings are defined programmatically using javax.servlet.SessionCookieConfig methods, those cookie settings will take precedence over the cookie properties defined here.

[How To] - Fix "Offending RSA key" error

Occasionally, when you try to SSH to some server, you may run into the following Offending RSA key error:

To fix this issue, you simply need to edit the file ~/.ssh/known_hosts and remove the particular line that caused the error. In the above example, the following line is crucial:

It means that the offending key is in line 10 of the known_hosts file. So just open the file, delete everything on line 10, save the file and you're done :). 

Try the SSH command again! Everything should be working normally now.