Authentication using Zend_Amf

Kevin Schroeder writes; I forget why, but a few days ago I started doing some digging around with authentication in Zend_Amf_Server. I had figured that I would add an adapter to the Zend_Amf_Server::setAuth() method and that would be it.

But I was wrong.

AMF allows for multiple request bodies to be sent at the same time. Of those there are several “special” types of commands. One of those commands is logging in. What this means is that you don’t need a method that logs someone in for you. Zend_Amf_Server handles authentication separately from your service classes.

Authentication for Zend_Amf_Server will generally use a combination of Zend_Auth and Zend_Acl components. Zend_Auth is used to provide the credential verification while Zend_Acl is used to validate that the current user user can access the requested service method. It is actually a relatively trivial task to restrict access to non-logged in users using the method that I will describe here.

The first step in the process is to create an authentication adapter. It really doesn’t matter what you’re using. What matters is that the adapter returns an identity object with a property called “role”. The built in ACL handle expects this to be part of the identity object.


class Auth extends Zend_Amf_Auth_Abstract
{
const LOGGEDIN_ROLE = 'loggedin';

public function authenticate()
{
$identity = new stdClass();
$result = Zend_Auth_Result::FAILURE;

// Do a proper login, y'all
if ($this->_username == 'test' && $this->_password == 'test') {
$identity->role = self::LOGGEDIN_ROLE;
$result = Zend_Auth_Result::SUCCESS;
} else {
$identity->role = Zend_Amf_Constants::GUEST_ROLE;
}

return new Zend_Auth_Result($result, $identity);
}
}

The Auth class extends Zend_Amf_Auth_Abstract because Flex seems to require username and passwords as being the only mechanism for passing credentials. The abstract class defines a method that hooks in with the special commands and passes the special credentials to the special adapter. Clearly your authentication mechanism should be better than the one that I put in here, but you’ll get the idea. The most important part is adding the role property to the identity object and passing it to the Zend_Auth_Result object.

Then in your gateway you need to add this adapter as well as create an simple ACL.


$server = new Zend_Amf_Server();
$server->addDirectory(realpath(__DIR__.'/../services'));

$acl = new Zend_Acl();
$acl->addRole(Auth::LOGGEDIN_ROLE);
$acl->allow(Auth::LOGGEDIN_ROLE);
$server->setAcl($acl);

$auth = new Auth();
$server->setAuth($auth);

echo $server->handle();

This adds the new Auth role to the ACL and says that it has access to everything. Since there is no place where I allow guest access (denoted by Zend_Amf_Constants::GUEST_ROLE in the adapter) guest requests will be denied.

With just this little bit of code you now have a mechanism that will provide restricted access to all of your service objects.

via Kevin Schroeder’s blog – Zend Technologies.

Zend Framework 1.10.4 Released – Notably Zend_Amf 200-300% faster

On behalf of the Zend Framework community, I’m pleased to announce the immediate availability of Zend Framework 1.10.4, our fourth maintenance release in the 1.10 series. You can download it from our downloads page:

http://framework.zend.com/download/latest

This release includes approximately 50 bugfixes, the majority of which were contributed during our Bug Hunt Days two weeks ago. The fixes contributed help stabilize and improve the 1.10 series.

Three fixes in particular are worth noting:

* ZF-7493: an important serialization improvement in Zend_Amf that has
been benchmarked as providing 200-300% faster serialization of large
datasets.

* ZF-9263: a fix to Zend_Loader::isReadable() to fix a regression found
on Windows platforms. This fix should eliminate most if not all
raised warnings that occurred during resource and plugin loading.

* ZF-9504: a patch was applied to Zend_XmlRpc_Value to make value
generation more efficient. Benchmarks and profiling show enormous
changes on large datasets: in one example, memory usage drops from
>1GB to 20MB, while dropping from execution times of >60s to around
10s.

We’d like to thank everyone who committed time, code, and translations since the 1.10.3 release — the community has been quite productive!


Matthew Weier O’Phinney