views:

220

answers:

5

I am playing about with the Zend Framework at the moment and I have a written the authentication code using Zend_Auth. I am trying to find a way to ensure that the user is logged in before they can view anything but I don't want to do it on a per controller basis.

I am thinking a plugin, but all the books I have on it are pretty rubbish in this respect.

+2  A: 
Zend_Auth::getInstance()->hasIdentity()

You can use this to determine if the user is logged in, and then use the redirector to redirect to the login page if not.

However, the easier way is to use a Redirector Zend Controller Action Helper.

Robert Harvey
I'm specifically looking for a method of doing this before I hit the controller. I know the code I would need to write to check if they are logged in but I need to do it before I reach the controller stage.
xenon
Would the Redirector Zend Controller Action Helper link I posted above work?
Robert Harvey
It would indeed but i would need to hit the controller before i could use it. And I am hoping to avoid putting this in the controller. I will need to redirect eventually. Thanks for the link
xenon
A: 

I was pondering the same subject lately (ZF newbie), and thought about doing the authentication checks in the bootstrap (maybe with a list of "bypassed" controllers/actions).

Flavius Stef
+1  A: 

A plugin is a good idea. I answered to a similar question here:

How do i centralize code from my init functions in all controllers ?

Also check the documentation page Zend Controller Plugins

Boris Guéry
Thank you for the links
xenon
+1  A: 

Look into Zend___Acl which can be used to define whether a user has access to certain resources. A resource can be pretty much anything, but in this context you can use the ACL to define your controllers and actions as resources. Each logged in user is then assigned a number of roles (we store them in a database). In a plugin you check the request for the Controller and Action, after routing is complete. Gather the roles of the user through the Zend_Auth and check them against the ACL. If the ACL says the user has permission to access the resource, do nothing, else you can forward/redirect to your error controller and print the error.

// Pseudo-code. You need to define the ACL and roles somehow.
class AclPlugin extends Zend_Controller_Plugin {
    public function routeShutdown(Zend_Controller_Request_Abstract $request)
    {

        $controller = $request->getControllerName();
        $action = $request->getActionName();
        $roles = Zend_Auth::getInstance()->getRoles();
        $acl = new MyAcl();
        if($acl->hasAccess($roles, $controller, $action)) { return; }
        // None of the user's roles gave her access to the requested 
        // controller/action, so re-write the request to the error controller
        $request->setControllerName('error')
                ->setActionName('authorizationFailed')
                ->setParam('resource', array('controller' => $controller
                                             'action' => $action));
    }
}
class MyAcl extends Zend_Acl {
    public function hasAccess($roles, $controller, $action) {
        foreach($roles as $role) {
            if($acl->isAllowed($role, $controller, $action)) {
                return true; // Simplified. Here we say if one of the user roles can
                             // access a resource, that is good enough. 
                             // Might want to do something a bit more complicated.
            }
        }
        return false;
    }
}
PatrikAkerstrand
+1  A: 

How about setting up a global controller that extends Zend_Controller_Action and then have your controllers extend from the global controller. Then your global controller puts the Zend_Auth::getInstance()->hasIdentity() in the init() or preDispatch?

joedevon