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 these tutorials too...

Thu, Jun 23, 2011

Extending Zend Auth - A Zend Config Adapter

So in the last installment of this series, I provided an introduction to Zend_Auth, Zend_Auth_Adapter_Interface and Zend_Auth_Result and how to implement Zend_Auth_Adapter_Interface to implement a basic test adapter that can be used as a mock object in your testing.

If you missed it, check it out now, then come back and we’ll continue on. If you’ve already read it, then let’s continue now.

As I indicated last time, whilst being a perfectly valid implementation, the Test adapter was rather basic and didn’t do very much. Like all good testing, you need flexibility and options. So in this installment, we’re going to build an adapter based around Zend_Config. This will lead quite nicely in to the last part in the series which uses the wonderful MongoDB as the underlying resource for the adapter.

Fri, Jun 17, 2011

Extending Zend Auth — The HowTo Series

Zend Auth, if you want to secure a Zend Framework app, along with Zend Acl, it’s essential. But do you know what it is? Do you know how to use it? Do you know how to extend it? Through this series I’m going to show you how to do all three.

Tue, Nov 15, 2011

Rename uploaded files with Zend Framework

Recently I was asked how to rename a file with the Zend Framework that used a Zend Form and Zend File element. They key requirement was that it should not be a hack or a kludged solution. So I thought I’d write a quick post to provide a simple example on how it was achieved.


Want more tutorials like this?

If so, enter your email address in the field below and click subscribe.

You can unsubscribe at any time by clicking the link in the footer of the emails you'll receive. Here's my privacy policy, if you'd like to know more. I use Mailchimp to send emails. You can learn more about their privacy practices here.

Join the discussion

comments powered by Disqus