Tuesday, March 6, 2012

CILogon and Liferay Part 6: Signing Out


This is part 6 of a set of blog posts detailing a procedure for setting up CILogon to provide authentication for a Liferay Portal.

So by now you've got your Liferay signing you in using your CILogon provider and all is well.  Your boss is pleased, and says "Can I try?"  Of course, you say, and slide the demo laptop over to him.  He clicks the "Sign Out" link in the upper right corner of the page and...

...you're still signed in.  He slides it back over to you, smile fading as you start clicking that link over and over, but Liferay's got you in an iron grip and ain't letting go.

Time to go back to your extension.

See, Liferay has a Struts driven LogoutAction object that clears the session and kills all the Liferay cookies... But it's not killing your CILogon cookies because, well, you made them, not Liferay. We need to modify that class to include the cookies your CILogonAutoLogin module keeps using to log you back in.

Grab the following file from the Liferay source code: com.liferay.portal.action.LopgoutAction.java and put it into your ext plugin in the corresponding folder.

About halfway down the file is a series of lines of code adding cookie objects to CookieKeys.  Right before those lines is a good place to add this code:



Cookie cILogonEmailCookie = new Cookie(
"CILOGON-USER_EMAIL", StringPool.BLANK);


if (Validator.isNotNull(domain)) {
cILogonEmailCookie.setDomain(domain);
}


cILogonEmailCookie.setMaxAge(0);
cILogonEmailCookie.setPath(StringPool.SLASH);
cILogonEmailCookie.setSecure(false);

Cookie cILogonNameCookie = new Cookie(
"CILOGON-USER_NAME", StringPool.BLANK);


if (Validator.isNotNull(domain)) {
cILogonNameCookie.setDomain(domain);
}


cILogonNameCookie.setMaxAge(0);
cILogonNameCookie.setPath(StringPool.SLASH);
cILogonNameCookie.setSecure(false);


CookieKeys.addCookie(request, response, cILogonNameCookie, false);
CookieKeys.addCookie(request, response, cILogonEmailCookie, false);


What's happening here is that we're replacing the cookies we created in SuccessServlet with new ones that will expire immediately. That way when the user comes back around in the request the CILogonAutoLogin module won't see the cookies and log the user back in.

Here's an important note... We're using the domain String object from the line

String domain = CookieKeys.getDomain(request);

earlier in the class.  This is not the full string you may expect.  For example, if this code is running on machine.mydomain.com, the domain that's returned here will be ".mydomain.com" so when you're setting this string in your SuccessServlet (back in part 2 of this series we called that variable TARGET_DOMAIN) make sure it matches!


I'm serious.  It took me a day and a half to figure out why Liferay was able to find the cookie, and yet wasn't overwriting the old cookie with the new one.  For this to work, the cookie domains must match exactly!

One quick note about setting that cookie back in SuccessServlet... I didn't go into specific detail but remember we NEVER hard code values!  If your domain is hard coded in that servlet for testing purposes fine... But as soon as possible move that string value into a config file or database entry or something.  Don't leave it in the compiled code.

--------------------------------------------
This project incorporates tools whose development was funded in part by the NIH through the NHLBI grant: The Cardiovascular Research Grid (R24HL085343)

No comments:

Post a Comment