Liferay 6.1 – where’s the password?

While coding for Liferay one might encounter the need to obtain current user’s password. For instance, Liferay’s Chat portlet does this to try logging in to Jabber server using same credentials that current user has for Liferay portal. The Chat portlet does it a bit wrong though, let’s see what’s the best way to do that.

First, Liferay doesn’t normally stores clear text passwords in DB – salted hashes are calculated and stored instead. This behaviour can be altered by setting the “passwords.encryption.algorithm” setting to value “NONE” as documentation specifies: http://www.liferay.com/documentation/liferay-portal/6.1/user-guide/-/ai/passwords
One should hardly ever do that, because in worst case leaking DB of salted hashes would be much less of a problem than leading DB full of clear text passwords.

Second, Liferay doesn’t store clear text password in RAM for much longer than it takes to calculate the hash (and well, for GC to run cleanup). This can be altered by setting the “session.store.password” setting to “true” as specified in another part of documentation: http://www.liferay.com/documentation/liferay-portal/6.1/user-guide/-/ai/session
One should try to avoid that too because otherwise memory dumps will contain passwords of users that were recently logging-in. This is what Chat portlet does though.

So, the right way in my opinion is to implement custom authenticator, in accordance with this piece of official documentation: http://www.liferay.com/documentation/liferay-portal/6.1/user-guide/-/ai/authentication-pipeline
When any user will be logging in to Liferay your Authenticator code will be called with clear text password as a parameter, and at the moment of the call you can perform necessary actions.

In case this is not enough and one needs to use the password not only in the moment of user’s login, there are options to do that too. Of course, you can do same thing as “session.store.password” does and store the password in session, maybe not as String object but as byte[] or char[] array to make it not so prominent in memory dumps. You can also encrypt it, so that getting it out of memory dump would require decryption.

However, thanks to suggestions of some people, we found out about a better way to to that: encrypt the password using key stored on server (for instance, in JVM’s keystore). This way we can decrypt and use password when necessary, but anyone who has the memory dump and knows encryption/decryption algorithm still can not decrypt the password because he lacks the key from server’s file system. That’s secure enough for anyone, I suppose (-:

Liferay in Action

It doesn’t seem to make much sense to post about Liferay since “Liferay in Action” book by Richard Sezov is out – that’s how good that books is. Really.

But, as it is mentioned in the book itself, Liferay is very alive at the moment, it is in dynamic development and new changes arrive all the time. Thus it makes perfect sense to comment on what has changed since the book is out (-:

I haven’t done any review of the changes made to Liferay in recent months, so no complete list in this post – maybe in future ones. But there are a couple of things that I want to mention right away because I stumbled across them in my day-to-day practice, which means other people will be stumbling over those often too, I presume.

First, the book explicitly states there is no way to add Servlet Filter to Liferay’s main portal web app without using EXT, that this cannot be accomplished via hook. Well, this is no longer true for 6.1hooks can add Servlet Filters to portal’s webapp now, hooray!
Continue reading