Extending Zend Auth With A Test Adapter

Zend_Auth provides a very extensible workflow for creating new adapters to suit your authentication needs. In this post, I start you off with a simple Test/Mock adapter.

In the first of this three part series, I’m going to cover a rather basic extension to Zend_Auth, a Test adapter. This adapter will allow you to test your application through being able to provide a mock object for authentication.

What is Zend Auth?

If you’re not familiar with Zend Auth, it’s the component of the Zend Framework that provides the ability* to confirm if a user is who they say they are or not*. What it does not do is confirm if the user, after being identified, *is allowed to perform a given action or not*. That’s left to Zend_Acl, which is not the subject of this post. For further specifics about it, please consult the online documentation.

How Do You Extend Zend_Auth?

Zend_Auth makes it very simple to create a new adapter that specifically suits your needs. If you have a look at Zend_Auth_Adapter_Interface, which all auth adapters implement, you’ll see that there’s only method required to be implemented, which is authenticate.

When you implement this method, you only have to keep two things in mind:

  • The method has to return a** Zend_Auth_Result object**
  • The method can throw a Zend_Auth_Adapter_Exception should something go wrong

If you look in the manual for details on Zend_Auth_Result, you’ll see that the object is very simple. It has four methods and six class constants that we can work with.

Zend_Auth_Result Methods

  • IsValid – Was the request valid (a success)
  • getCode – What was the return code from the method (see the class constants below)
  • getIdentity – Retrieve the returned user identity object (assuming the login was a success)
  • getMessages – Retrieve any error messages encountered during the authentication process

Zend_Auth_Result Class Constants

  • Zend_Auth_Result::SUCCESS
  • Zend_Auth_Result::FAILURE
  • Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
  • Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
  • Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
  • Zend_Auth_Result::FAILURE_UNCATEGORIZED

Let’s Build Our Adapter?

Ok, now let’s get going and create our new adapter. Firstly, create a standard Zend Framework project in your web server’s  directory root and in the application config ini file (application.ini), I’m assuming that you’re using Zend_Application here, add in the following to make our class namespace available to the project:

autoloaderNamespaces[] = "MaltBlue_"

I’m calling it “**MaltBlue_**” because it’s nice and simple and is easily distinguishable from any other. Now after that’s done, create the directory structure **MaltBlue-> Auth -> Adapter** under library and in that, create a new file Test.php

In that file, place this so that we have a basic working adapter:

<?php
class MaltBlue_Auth_Adapter_Test implements Zend_Auth_Adapter_Interface {

}

As stated earlier, we only need to implement one method, authenticate. As this will be a simple implementation, we’re going to cheat a bit with it. We’re going to define two class constants, which will store the username and password, you could use protected or private class member variables instead.

Now there could be heckles, cries or disbelief, gnashing of teeth or worse at this stage. But I’m not looking to have this be the most secure or brilliant piece of work known to man. I know there are obvious problems here, but this is to highlight the process of extending Zend_Auth. So just for the moment, bear with me.

So add in to your class the following:

const DEFAULT_USERNAME = 'matthew';
const DEFAULT_PASSWORD = 'password';
protected $_username;
protected $_password;

Now, we need to setup the constructor. In our case, as this is a simple adapter, it’s going to have only two parameters, $username and $password. In the constructor, we’re going to assign the values passed in to the equivalent member variables.

The Heart of the Adapter

public function authenticate()    {
  if (empty($this->_username) || empty($this->_password)) {
    throw new Zend_Auth_Adapter_Exception();
  }
  if ($this->_username != self::DEFAULT_USERNAME || 
      $this->_password != self::DEFAULT_PASSWORD) {
    return new Zend_Auth_Result(
      Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, array()
    );
  }	       
  return new Zend_Auth_Result(
    Zend_Auth_Result::SUCCESS,
      array(
        'username' => self::DEFAULT_USERNAME,
        'firstName' => self::DEFAULT_PASSWORD
      )
    );   
}

As you can see, it’s pretty simple. We first check if a username and password’s been set. If not, as you’d expect, we can’t continue, so we throw an exception. Following this, we do our “authentication”.

We check if the username and password supplied are equal to the internal values we’ve pre-defined. If so, we return a new Zend_Auth_Result object that contains the username, first name and last name that we’ve stored in the object and the code of SUCCESS.

If they don’t, we return a Zend_Auth_Result object with an empty identity and a code of FAILURE_CREDENTIAL_INVALID. Now really, that’s it. We could continue to extend the example to cater to the other code constants, but you should get the idea from what’s been done so far.

Let’s Use the Adapter

So let’s get in and use this little adapter we’ve created. In your default index controller, place the following:

$username = 'matthew';
$password = 'password';
$auth = Zend_Auth::getInstance();

$adapter = new MaltBlue_Auth_Adapter_Test();
$adapter->setUsername($username)
        ->setPassword($password);
$result = $auth->authenticate($adapter);

switch ($result->getCode()) {
  case (Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID):  
    print 'Sorry your account is NOT available';
  break;
  case (Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS):
    print 'There appear to be multiple users with that username';
  break;
  case (Zend_Auth_Result::SUCCESS):
    print 'Account available';
  break;
}

As you can see, we’ve retrieved a Zend_Auth instance and created an instance of our test adapter that we’ve just developed. Using the fluent interface style, we’ve set the username and password and passed the test adapter to the Zend Auth instance’s authenticate method.

Following that, we’re using to use the getCode method of the returned result object to identify if our authentication’s succeeded or not, looking at three cases. In the case above, when it’s run, you’ll see “Account available” printed out. Changing the combination will return  “Sorry your account is NOT available”.

Now I admit, this didn’t show every variation that you can use, but it covers the basics of extending Zend_Auth to create an adapter that suits your specific needs. I encourage you to play with the code and extend it to do that.

In Conclusion

But this example is sorely lacking a way of more flexibly setting the properties of the object, using something like, say Zend_Config. In the next installment in the series, I’m going to show you how to do just that - using Zend_Config, we’re going to implement a Config adapter that can be initialised with a config object, based on any one of Ini, Xml, Yaml or Json config files.

I hope that this first post has show just how easy it is to work with Zend_Auth and gives you an idea as to the possibilities that it affords you.


You might also be interested in...


comments powered by Disqus

Books

Buy Mezzio Essentials. Learn the fundamentals that you need, to begin building applications with the Mezzio framework today! Buy Now

Latest YouTube Video

Learn how to write SQL queries in PhpStorm