Question

I've recently started using Zend Framework and I'm still pretty used to session_start, and assigning variables to certain session names (ie: $_SESSION['username'] == $username)

I'm trying to figure out how to do something similar to this in Zend. Right now, my auth script checks the credentials using LDAP against my AD server and, if successful, authenticates the user.

I want to create a script that will allow an admin user to easily "enter" someone else's session. Let's say admin1 had an active session and wanted to switch into user1's session. Normally I would just change the $_SESSION['username'] variable and effectively change the identity of the user logged in.

But with Zend, I'm not quite sure how to change the session info. For what it's worth, here's my authentication script:

class LoginController extends Zend_Controller_Action
{
    public function getForm()
    {
        return new LoginForm(array(
            'action' => '/login/process',
            'method' => 'post',
        ));
    }

    public function getAuthAdapter(array $params)
    {
        $username = $params['username'];
        $password = $params['password'];
        $auth = Zend_Auth::getInstance();

        require_once 'Zend/Config/Ini.php';
        $config = new Zend_Config_Ini('../application/configs/application.ini', 'production');
        $log_path = $config->ldap->log_path;
        $options = $config->ldap->toArray();
        unset($options['log_path']);

        require_once 'Zend/Auth/Adapter/Ldap.php';
        $adapter = new Zend_Auth_Adapter_Ldap($options, $username, $password);

        $result = $auth->authenticate($adapter);

        if ($log_path) {
            $messages = $result->getMessages();

            require_once 'Zend/Log.php';
            require_once 'Zend/Log/Writer/Stream.php';
            require_once 'Zend/Log/Filter/Priority.php';
            $logger = new Zend_Log();
            $logger->addWriter(new Zend_Log_Writer_Stream($log_path));
            $filter = new Zend_Log_Filter_Priority(Zend_Log::DEBUG);
            $logger->addFilter($filter);

            foreach ($messages as $i => $message) {
                if ($i-- > 1) { // $messages[2] and up are log messages
                    $message = str_replace("\n", "\n  ", $message);
                    $logger->log("Ldap: $i: $message", Zend_Log::DEBUG);
                }
            }
        }
        return $adapter;
    }
    public function preDispatch()
    {
        if (Zend_Auth::getInstance()->hasIdentity()) {
            // If the user is logged in, we don't want to show the login form;
            // however, the logout action should still be available
            if ('logout' != $this->getRequest()->getActionName()) {
                $this->_helper->redirector('index', 'index');
            }
        } else {
            // If they aren't, they can't logout, so that action should
            // redirect to the login form
            if ('logout' == $this->getRequest()->getActionName()) {
                $this->_helper->redirector('index');
            }
        }
    }
    public function indexAction()
    {
        $this->view->form = $this->getForm();
    }
    public function processAction()
    {
        $request = $this->getRequest();

        // Check if we have a POST request
        if (!$request->isPost()) {
            return $this->_helper->redirector('index');
        }

        // Get our form and validate it
        $form = $this->getForm();
        if (!$form->isValid($request->getPost())) {
            // Invalid entries
            $this->view->form = $form;
            return $this->render('index'); // re-render the login form
        }

        // Get our authentication adapter and check credentials
        $adapter = $this->getAuthAdapter($form->getValues());
        $auth    = Zend_Auth::getInstance();
        $result  = $auth->authenticate($adapter);
        if (!$result->isValid()) {
            // Invalid credentials
            $form->setDescription('Invalid credentials provided');
            $this->view->form = $form;
            return $this->render('index'); // re-render the login form
        }

        // We're authenticated! Redirect to the home page

        $this->_helper->redirector('index', 'index');

    }
    public function logoutAction()
    {
        Zend_Auth::getInstance()->clearIdentity();
        $this->_helper->redirector('index'); // back to login page
    }
}

Is there any way to do what I have described? Thanks for any suggestions.

Was it helpful?

Solution

Given your code, the result of authenticating is stored in the PHP session through a Zend_Auth_Storage_Session object.

Calling Zend_Auth::getIdentity() gets access to the storage and returns the result if it is not empty. Likewise, you can change the stored identity by getting access to the underlying storage and changing its value. The actual identity stored as a result of authenticating with Zend_Auth_Adapter_Ldap is just a string value representing the LDAP username.

To effectively change the logged in user, you can do:

Zend_Auth::getInstance()->getStorage()->write('newUserName');

This assumes the default behavior which should be in place given your code.

What I do in my applications after successful authentication is to create a new object of some User model, and write that to the Zend_Auth session so that I have more information about the user available in each session, so you should be aware that different things can be in the storage depending on the application.

This is what I do for example:

$auth       = new Zend_Auth(...);
$authResult = $auth->authenticate();

if ($authResult->isValid() == true) {
    $userobj = new Application_Model_UserSession();
    // populate $userobj with much information about the user
    $auth->getStorage()->write($userobj);
}

Now anywhere in my application I call Zend_Auth::getInstance()->getIdentity() I get back the Application_Model_UserSession object rather than a string; but I digress.

The information that should help you is:

$user = Zend_Auth::getInstance()->getIdentity(); // reads from auth->getStorage()

Zend_Auth::getInstance()->getStorage()->write($newUser);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top