Zend Framework Access Control using a Controller Plugin

Written by James Mansson on March 13, 2013 Categories: Access Control, AJAX, Zend Framework 1

Perhaps the simplest way to enforce access control in a Zend Framework application is to use a controller plugin. Controller plugins are a mechanism for executing code at certain points during the controller process. In our case, we want to check whether a user’s request should be permitted before the request is transferred to the appropriate action handler.

By convention, the plugins are stored in the /application/plugins directory. Assuming that the application namespace is Application and we are using the standard autoloader, the name of the plugin class will have the prefix Application_Plugin_ and the name of the file containing the class will be the name minus the prefix plus the PHP suffix. We shall be calling our plugin Application_Plugin_AccessControl, and the implementation of the class will reside in the file /application/plugins/AccessControl.php.

Plugins should be derived from the base class Zend_Controller_Plugin_Abstract. They will implement one or more functions depending on where they need to execute the code in the controller process. In our case we want to implement the preDispatch function.

The skeleton for the class code is as follows:

class Application_Plugin_AccessControl extends Zend_Controller_Plugin_Abstract
{
	public function preDispatch(Zend_Controller_Request_Abstract $request)
	{
		// TODO: Insert access control code here
	}
}

The method we use to decide on whether a user depends on our application. It can vary from a simple check as to whether the user is logged in, to a complex check against a Zend_Acl object.

Let’s assume that we have used Zend_Auth to handle the user log in. We can then check whether the user is logged in as follows:

$loggedIn = Zend_Auth::getInstance()->hasIdentity();

If the user is logged in, we don’t need to do anything. However, if the user is not logged in, we want to display the login page rather than the page requested. This can be achieved by something like this:

if (!$loggedIn)
{
	$request->setModuleName('default');
	$request->setControllerName('login');
	$request->setActionName('index');
}

What this does is change the module/controller/action handler to which the request will be despatched. Rather than ending up on the page requested, the user will see the login page instead. In this case the login page is handled by the default module/login controller/index action handler. Naturally, a different module/controller/action combination could be used.

Some applications need to take into account AJAX requests as well as full page requests. In the case of an AJAX request that is denied due to access control, it clearly doesn’t make sense to return the login page. Instead we want to return something more appropriate.

The first step is to extend the above code as follows:

if (!$loggedIn)
{
	if ($request->isXmlHttpRequest())
	{
		$request->setModuleName('default');
		$request->setControllerName('error');
		$request->setActionName('access-denied');
	}
	else
	{
		$request->setModuleName('default');
		$request->setControllerName('login');
		$request->setActionName('index');
	}
}

This makes use of the isXmlHttpRequest function of the request object to determine whether the request is an AJAX request. If it is an AJAX request, the default module/error controller/access-denied action handler is used instead. A simple implementation for this handler function would be:

public function accessDeniedAction()
{
	// Disable the layout and don't render the view script
	$this->_helper->layout->disableLayout();
	$this->_helper->viewRenderer->setNoRender(true);

	// Set the response code
	$this->getResponse()->setHttpResponseCode(403);
}

The calling JavaScript function will need to decide how best to respond to the 403 code.

 

No Comments on Zend Framework Access Control using a Controller Plugin

Leave a Reply

Your email address will not be published. Required fields are marked *