SSO via Facebook

Liferay 6.0 now comes with an additional Single Sign-On option - Facebook SSO using OAuth 2.0.  Setup is quite easy.  Let me walk you through the steps below.

1. In order for Facebook SSO to work, you first have to have a Facebook application account.  If you don't already have one, you can get more information here: developers.facebook.com/docs/guides/web

2. Once you have a Facebook application account (and ID), you'll need to edit settings under the Web Site tab.  Fill in the Site URL text field and the Site Domain text field.  If you're testing locally, you can set the Site URL as http://localhost:8080 and the Site Domain to be localhost.  I've added an entry in my hosts file, so lportal.com would hit my local tomcat at port 8080.  Below is an example of what I've entered.  Click Save when you're done with your settings.  Note: If you do change your domain, make sure you update all the relevant areas.

  • Facebook side (pictured below)
  • Liferay side (Control Panel -> Settings -> Authentication -> Facebook -> Redirect URL
  • Community Virtual Host (Control Panel -> Community -> Actions button -> Settings -> public domain)
  • your local environment's host file (i mapped 127.0.0.1 to lportal.com)

Facebook Connect Settings

3. After entering these settings on the Facebook side, you now need to configure your Liferay portal.  First, log in with your administrator account.  Go to the Control Panel.  On the left menu under the instance you want to enable Facebook SSO, click on Settings.  Then click Authentication on the right menu, and lastly click on Facebook.  In this section, you want to first check the checkbox to enable Facebook SSO.  Next, fill in the Application ID which is a numeric ID (not to be confused with the application key), the Application Secret (don't tell/show anyone this), and lastly, update the domain part of the Redirect URL if not using localhost (I changed mine from localhost to lportal.com).  Below is what I've entered.  Click Save when you're finished.  (If you're not using localhost, make sure you've already updated the community's public virtual host, AND that you're accessing the site using this virtual host domain.)

Liferay Portal Authentication Facebook Settings

4. Now you're ready to test it.  Log out of your administrator account in Liferay portal.  When you're on the login page, you should now see the Facebook link under the password field.

5. Clicking on the Facebook link should do one of two things.  If your browser already has a Facebook session, it will try to log you in with that Facebook account.  If no Facebook session exists on your browser, it will prompt you to login with your Facebook credentials.  Once you've granted access, Liferay portal will ask Facebook for the primary email address of that account you logged in with.  Liferay portal will search its database for that email address.  If found, it'll log you in automatically, if not, you will see the prompt below.

6. User can choose to create an account on your Liferay portal simply by clicking the Add Account button.  Liferay will then ask Facebook for the first name, last name, gender, and email address of the account.  It will also ask whether the account is validated by Facebook for security reasons.

NOTE: if your Facebook application you setup earlier is in Sandbox mode, only the developers of your Facebook application listed will be able to login successfully.

7. That's all there is to it!  Your users can now login with their Facebook credentials to your site!  If they don't already have an account on your site, sign up is that much easier.

 

We plan to add additional features in the near future.  Here's a list of them so far:

  • Allow Liferay accounts to link to Facebook accounts by facebook user ID (so email addresses don't need to be the same).
  • Make it configurable whether the Add Account option should be presented to user if no accounts were found on Liferay portal.
  • For the add account feature, also ask Facebook for user's birthday.  This will be configurable whether birthday is required.

Update 2/23/2011: Since the Facebook "My App" interface has changed, I've taken a new screenshot and replaced the old one with the new.

Blogs
Great Post,could you please help me how to do the same with other Social Networks like Flicker,youtube,Buzz,Twitter,etc..
greate !!! thanks Wilson, know that we are logged to facebook, can we have facebook wall or images in liferay? is there a way to do that?

thanks a lot for the info. Greate Job!!
hi M. Ahamed, I'm not as familiar with those APIs, but if you have specific questions regarding their integration, feel free to ask them in our forums and we'll do our best to shed some light when possible!
Hi Wilson Man, thank you for replay we could Reference this pages.
Twitter:http://dev.twitter.com/pages/sign_in_with_twitter
Flicker:Reference link : http://www.flickr.com/services/api/
Youtube:http://code.google.com/apis/youtube/2.0/reference.html
Buzz:http://code.google.com/apis/buzz/v1/getting_started.html
This feature is great and I've already enabled it with the site I'm currently developing. However, when a user logs into the portal with facebook after creating an account they are taken back to the current page and not to the default landing page.
Andrew, are you using the "default.landing.page.path" property to set the landing page? I just tried it and you're right, it doesn't land on that page after autologin, but it also doesn't land there after normal login for me, are you experiencing the same for normal login?
In Liferay 6.0.4, via control Panel.portal.settings.Navigation.Default Landing Page I have set "/web/members/home". When logging in via the normal email/pass combo the landing page is handled correctly, when login with facebook the user returns to the current page, just authenticated.
i see, i'm on 6.0.5 and will have to check with the core team. thanks for the feedback!
Hi Wilson,

This is a very helpful blog. I am also trying to have the similar sign on process using with Google using oauth token.

Is it possible if you can provide the step by step process for the build which has been done for Facebook, so that i can implement the same using Google?

I have already enable the ldap authentication, but with that i want to provide google login as well, the user are not stored in liferay DB. The main user storage is in Active Directory. SO in such scenario how to enable both the sign on process.

Please help as i am new with the ouath authentication process.
This is so cool , great feature to attract more site traffic
Thanks for configuration steps
great feature! If using exclusively this method of authentication, I guess I don´t need a LDAP as there are no credentials to store, right?

thank you
hi wilson,

I tried to use the SSO via Facebook, but after clicking "Add Account" nothing happens.
No user added, no login

Any Idea?

I'm testing on localhost:8080, liferay 6.0.5

btw. the facebook form for Application registration has changed
Hi Enric,

I did some investigation on this and this is what I could figure out:

The FacebookConnectAction class performs all actions related to facebook SSO login. This
class expects a boolean parameter 'verified' in the jsonObject received from Facebook, but this parameter is somehow not being received and it returns from the following lines without doing anything:

if (!jsonObject.getBoolean("verified")) {
return;
}

I just commented the above lines (twice in the code) and it worked for me. Also, the size of the email column in the _user table needs to be increased to accommodate dynamically generated email id which is larger than default column size.

Thanks,
Ravikant
thanks Ernst and Ravikant for bringing this to my attention. I will test this later this week.
actually, i just tested it, and it's working fine for me. the "verified" is still returned by FB. you probably need to have a valid FB account for this to work. If you think there's a case where we may want to allow "unverified" FB accounts to work, let me know and I can make that configurable.
Making it configurable would be a good idea. Like us, who are not sure what is wrong with our FB accounts, this issue can bother others too.

Will discuss this issue with FB support to know what may be causing this.

Thanks
Hi Wilson,

I need the information regarding the authentication method based on token which has been used for Facebook based SSO. I want the similar kind of implementation on my portlet method for implementing it with Google. Google have the user Email address store in the google database and sending the same in the authentication token.

All the user details are stored in the Active directory, on the basis of authentication token if the user is not present i the portlet database and if the user exist in the Active directory i want the application to authenticate the user based on the trust established between the Portal and Google.

Please suggest as i am stuck on the authentication aspect of the user, i have already started with the custom portlet to get the oauth based token and validating the same, but how to proceed with the next step.

Thanks in advance!!
Hi,

we're stuck on the same issue of Zhou Wu (we are using liferay 6.0.5) : facebook redirect and authorization seems to work fine, but when it redirects back to liferay, it's still unauthenticated. We've also noticed that the column USER_.facebookId is null.

What we tried was to:

- create an ext plugin - using liferay 6.0.5 SDK(attached) - including docroot/WEB-INF/ext-impl/src/com/liferay/portal/action/login/FacebookConnectAction.java , copied from the 6.0.5 SVN tag, applying the patches mentioned by Ravikant Kumar

- alter USER_ table, modifying column emailAddress from varchar(50) to varchar(255), as suggested by Ravikant Kumar

- Add some logs statements to see if liferay is picking up our version or not.

Logs statements are logged, but still does not work; no errors, no warnings, no exceptions.

Any idea? Thanks.
thank you all for reporting this issue to me and for giving me such detail. I'm in the process of getting the latest from the 6.0.x branch to see if the issue is there. I'm hoping to report back no later than the end of this week, hopefully sooner.
in rev 73726 facebook option doesnt work.
hi All, I've gotten a chance this morning to test with 6.0.5 and no bug was found. I was able to import my facebook account (and also SSO) into a clean Liferay portal 6.0.5 CE.

I've added a few additional notes to my instruction above. For those of you having issues with redirect, make sure your domains are set correctly. On Facebook's side, make sure the Site URL field has the proper port, etc.

As for facebook accounts that are not verified, it's simple to verify your account. If you do not want to for whatever reason, you can follow the steps outlined in the comments above to override the verification code on liferay side.

Otherwise, Facebook SSO is working fine in 6.0.5 CE. thank you all.
Hey Wilson ! Well the issue remains persistent. Here's the scenario:

My Facebook redirect URL setting :
http://portal.xxxxxx.com/c/login/facebook_connect_oauth

Liferay Main configuration:
Virtual host : portal.xxxxxx.com
Default landing page : /web/group/announcements

If I log a user in without using Facebook SSO, it correctly redirects him to portal.xxxxxx.com/web/group/announcements post authentication.

Whereas, If I login the user using Facebook, the user is sent to portal.xxxxxx.com/home and not the page that I have set as the default landing page.

Do you know why that might be happening and what can I do to ensure that even FB authenticated users go to the same landing page ?

Thanks.
hi Abhay, thanks for your feedback. With regards to the post authentication redirect, the Facebook SSO implementation terminates at the auto-login phase within the whole login process. The rest is governed by Liferay's auto-login mechanism. So while there isn't anything the FB SSO feature can add to help with this redirection issue you're having, you may have better luck looking into the auto-login implementation to find the answer.
Where does the screenshot in step 2 come from? Is it from facebook site or liferay web portal? Please help.
it's on facebook.
Thanks. However, I just couldn't make it work for me. At some point, it did direct me to facebook page asking for permission when I tested with my facebook account. Now every time I click the facebook button on the login page, it simple returns the original page showing "sign in" page. What could be wrong here?
Hi. On the second screenshot you have Facebook button in authentification section. I have just downloaded liferay-tomcat-portal (version 6.0.5), installed it and in authentification section I have no any facebook button. What is wrong? Can you help me? Thanks.
Problem is solved. I get confused with archives and used earlier version of liferay. I have setup last version of liferay and everything is OK.
Hi Wilson,

I am getting following error when trying to do facebook login:
{code}
ERROR [jsp:154] com.liferay.portal.security.auth.PrincipalException: /home?p_auth=TtY5d06h&p_p_id=58&p_p_lifecycle=1&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&_58_struts_action=%2Flogin%2Ffacebook_connect&_58_redirect=http%3A%2F%2Fdemo.componence.com%2Fhome%3Bjsessionid%3D41F0CD9814F2575F89983DED0100F5C1%3Fp_p_id%3D58%26p_p_lifecycle%3D0%26p_p_state%3Dnormal%26p_p_mode%3Dview%26p_p_col_id%3Dcolumn-1%26p_p_col_count%3D1%26_58_struts_action%3D%252Flogin%252Ffacebook_connect_add_user
at com.liferay.portal.struts.PortletRequestProcessor.process(PortletRequestProcessor.java:164)
at com.liferay.portlet.StrutsPortlet.processAction(StrutsPortlet.java:186)
at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:70)
at com.liferay.portal.kernel.portlet.PortletFilterUtil.doFilter(PortletFilterUtil.java:48)
at com.liferay.portlet.InvokerPortletImpl.invoke(InvokerPortletImpl.java:652)
at com.liferay.portlet.InvokerPortletImpl.invokeAction(InvokerPortletImpl.java:687)
at com.liferay.portlet.InvokerPortletImpl.processAction(InvokerPortletImpl.java:360)
at com.liferay.portal.action.LayoutAction.processPortletRequest(LayoutAction.java:768)
at com.liferay.portal.action.LayoutAction.processLayout(LayoutAction.java:571)
at com.liferay.portal.action.LayoutAction.execute(LayoutAction.java:229)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
at com.liferay.portal.struts.PortalRequestProcessor.process(PortalRequestProcessor.java:152)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at com.liferay.portal.servlet.MainServlet.callParentService(MainServlet.java:508)
at com.liferay.portal.servlet.MainServlet.service(MainServlet.java:485)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
{code}

I am using liferay version ce 6.0.5
I added a facebook application.
Enabled facebook login and updated add_id,secret_key,redirect_url.

Now on login portlet, clicked to facebook login.. redirected to facebook.. allowed my app, back to my portal, clicked add account button. then after it redirected me back to sign in page without making me signed in.
And with this exception in the logs.

However my user has been added in the users table.
hey Gaurav, i'll try my best to take a look when I get a chance. sounds like the problem has to do with the auto-login after everything was validated.
Hey Wilson ! Great tutorial emoticon

I'm being able to authenticate and log users in (via Facebook) but the default.landing.page.path seems to have become ineffective. I've also set auth.forward.by.last.path to true. But post successful login, I am unable to redirect the user to a page of my choosing. Can you help me here ?
Hi, thanks for this feature!
Is it possible to get accessToken in portlet?
hi Vaclav, the access token is stored as a HttpSession attribute. You can retrieve it from the HttpSession using this constant: WebKeys.FACEBOOK_ACCESS_TOKEN
Hi Wilson, thanks for your reply. I'm trying to get accessToken from session, but without success :-(. What I did and try so far:

1) In liferay-portlet.xml I have private-session-attributes set to true for my portlet
2) In portal-ext.properties I have session.shared.attributes=FACEBOOK_
3) In my controller I tried:

HttpServletRequest request = PortalUtil.getHttpServletRequest(portletRequest);
request = PortalUtil.getOriginalServletRequest(request);
HttpSession session = request.getSession();
String token = (String) session.getAttribute(WebKeys.FACEBOOK_ACCESS_TOKEN);

and

PortletSession session= portletRequest.getPortletSession();
String token = (String) session.getAttribute(WebKeys.FACEBOOK_ACCESS_TOKEN, PortletSession.APPLICATION_SCOPE);

In both cases is returned token null.

Am I missing something?
Many thanks in advance!
Hi Vaclav,

I think you need to add this to your portlet-ext.properties:
#
# Set a comma delimited list of attribute names that will be copied to the
# new session when the property "session.enable.phishing.protection" is set
# to true.
#
session.phishing.protected.attributes=HTTPS_INITIAL,LAST_PATH,FACEBOOK_ACCESS_TOKEN

The reason for that additional attribute is that chances are, your session.enable.phishing.protection property is defaulted to true. This means that right after login, the user gets a new session object. Adding the FACEBOOK_ACCESS_TOKEN to the property above would cause that attribute to be copied over to the new session.
Hi Wilson, thanks for reply again.
I tried to add session.phishing.protected.attributes, but there is still no FACEBOOK_ACCESS_TOKEN in token :-(.
I also looked into AttributeNames enumerations inside sessions:
- HttpSession AttributeNames is empty
- AttributeNames in PortletSession (ApplicationScope) are: LIFERAY_SHARED_AUTHENTICATION_TOKEN, USER_ID, LIFERAY_SHARED_VISITED_GROUP_ID_RECENT, org.apache.struts.action.LOCALE, LIFERAY_SHARED_VISITED_GROUP_ID_PREVIOUS
- AttributeNames in PortletSession (PortletScope) is empty
hi Vaclav, i haven't gotten a chance to look into that yet. one last thing i would say to check is the portal properties listed in control panel. see if you see the added attribute key there.
hi Wilson, in the portal properties in control panel are all defined attributes: session.phishing.protected.attributes HTTPS_INITIAL,LAST_PATH,FACEBOOK_ACCESS_TOKEN and also
session.shared.attributes FACEBOOK_ACCESS_TOKEN
hi Vaclav, got a chance to look into this issue over the weekend, and found that the code that transfers session attributes from old session to new during the login process isn't called when login through the AutoLogin hook/process. I plan to inquire about this internally.

In the meantime, if you have more questions, can you start a Message Board thread on this topic? I would rather discuss this there since the MB is more geared towards deeper discussions like this one.

again, thanks for bringing this to my attention!
Vaclav, i've gotten a chance to investigate a bit more and we've deemed this to be a bug in the auto-login process. I've gone ahead and created a ticket for it.

http://issues.liferay.com/browse/LPS-15895
thanks again!
I thank you for dealing with that, i'll be watching that ticket and looking forward for solution. Have a nice day!
try

String token = (String)session.getAttribute("FACEBOOK_ACCESS_TOKEN");

in jsp and then send it to your action in a hidden field or something.

I had the same problem as you and it worked by doing that.
Thanks for tip Andreas, but it's still null :-(. cant be there some problem with listeners? I have both RequestContextListener and ContextLoaderListener defined.