I implemented a similar thing not so long ago. The basic concept follows in the sample code.
I created my own configAcl.php file, which is loaded into the bootstrap file, in my case it is index.php. Here is how it will be in your case:
$acl = new Zend_Acl(); $roles = array('admin', 'normal'); // Controller script names. You have to add all of them if credential check // is global to your application. $controllers = array('auth', 'index', 'news', 'admin'); foreach ($roles as $role) { $acl->addRole(new Zend_Acl_Role($role)); } foreach ($controllers as $controller) { $acl->add(new Zend_Acl_Resource($controller)); } // Here comes credential definiton for admin user. $acl->allow('admin'); // Has access to everything. // Here comes credential definition for normal user. $acl->allow('normal'); // Has access to everything... $acl->deny('normal', 'admin'); // ... except the admin controller. // Finally I store whole ACL definition to registry for use // in AuthPlugin plugin. $registry = Zend_Registry::getInstance(); $registry->set('acl', $acl);
Another case is that you want to allow normal user action only to a "list" on all of your controllers. This is pretty simple, you should add a line like this:
$acl->allow('normal', null, 'list');
Then you must create a new plugin that automatically checks for credentials when there is a request for any action by the controller. This check is performed in the preDispatch () method, which is called before each call to the controller action.
Here is AuthPlugin.php:
class AuthPlugin extends Zend_Controller_Plugin_Abstract { public function preDispatch(Zend_Controller_Request_Abstract $request) { $loginController = 'auth'; $loginAction = 'login'; $auth = Zend_Auth::getInstance(); // If user is not logged in and is not requesting login page // - redirect to login page. if (!$auth->hasIdentity() && $request->getControllerName() != $loginController && $request->getActionName() != $loginAction) { $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector'); $redirector->gotoSimpleAndExit($loginAction, $loginController); } // User is logged in or on login page. if ($auth->hasIdentity()) { // Is logged in // Let check the credential $registry = Zend_Registry::getInstance(); $acl = $registry->get('acl'); $identity = $auth->getIdentity(); // role is a column in the user table (database) $isAllowed = $acl->isAllowed($identity->role, $request->getControllerName(), $request->getActionName()); if (!$isAllowed) { $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('Redirector'); $redirector->gotoUrlAndExit('/'); } } } }
The final steps load your configAcl.php and register AuthPlugin in the bootstrap file (possibly index.php).
require_once '../application/configAcl.php'; $frontController = Zend_Controller_Front::getInstance(); $frontController->registerPlugin(new AuthPlugin());
So this is the basic concept. I have not tested the code above (copy and paste and rewrite for showcase purpose only), so that it is not bulletproof. Just to give an idea.
EDIT
For clarity. The AuthPlugin code above assumes that the $ identity object is populated with user data (the "role" column in the database). This can be done during the login process as follows:
[...] $authAdapter = new Zend_Auth_Adapter_DbTable($db); $authAdapter->setTableName('Users'); $authAdapter->setIdentityColumn('username'); $authAdapter->setCredentialColumn('password'); $authAdapter->setIdentity($username); $authAdapter->setCredential(sha1($password)); $authAdapter->setCredentialTreatment('? AND active = 1'); $auth = Zend_Auth::getInstance(); $result = $auth->authenticate($authAdapter); if ($result->isValid()) { $data = $authAdapter->getResultRowObject(null, 'password');