I’ve recently been developing a website using the Zend Framework (ZF). The site needs user authentication, and Zend provides a nice authentication implementation, with an adapter for authentication against a database table. Since I’ve worked with the Joomla CMS a lot, I thought it would be nice to authenticate against a Joomla! user table.
The Zend DBTable Authentication Adapter
The default DBTable authentication adapter is easy to use. Just give it a table name and set the identity and credential columns:
$authAdapter = new Zend_Auth_Adapter_DbTable( $db );
You can even tell it to use MD5 (or other) encryption on the credential (password) column.
Joomla’s Salted Password Scheme
Joomla, though, uses a particular scheme for its passwords. First some random salt is generated (32 characters long), then the salt is appended to the plain text password, MD5 is applied, and finally a colon (:) and the salt are appended to that:
$stored_password = md5($password . $salt) . “:” . $salt
Because :salt is appended to the encrypted, already salted password, the DBTable authentication adapter doesn’t work out of the box. But, it was easy enough to extend the Zend_Auth_Adapter_DBTable class to add this functionality.
A Joomla Authentication Adapter
The new authentication adapter, My_Auth_Adapter_Joomla, extends Zend_Auth_Adapter_DBTable and just fills the constructor with default parameters. It then overrides two functions:
authenticate() and _authenticateCreateSelect().
The authenticate() function only needs to set the credential treatment to MD5, otherwise it is the same as the DBTable version:
$this->setCredentialTreatment( ‘MD5(?)’ );
Similarly, the _authenticateCreateSelect() only needs some slight changes. First, we need to look up the salt for the user:
// Get the salt for this user
$dbSelectSalt = $this->_zendDb->select();
->where($this->_zendDb->quoteIdentifier($this->_identityColumn, true) . ‘ = ?’, $this->_identity);
$result = $this->_zendDb->fetchRow($dbSelectSalt->__toString());
$parts = explode( ‘:’, $result[‘password’] );
$salt = @$parts;
Finally, we modify the credential-matching SQL code to allow for Joomla’s salting scheme:
$credentialExpression = new Zend_Db_Expr(
‘(CASE WHEN ‘ .
. ‘ = CONCAT(‘ . $this->_credentialTreatment . ‘,\’:’ . $salt . ‘\’)’, $this->_credential . $salt
. ‘ THEN 1 ELSE 0 END) AS ‘
(all we’ve done here is match the Joomla salting scheme).
All in all, the Zend Framework is built nicely to make such customization and extension easy and fast.
You can download the full class from the Projects area of this site.