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 (-: