Hi list, first time poster here so please be gentle ;-)

I'm getting up and running with Zend Framework for the first time and have googled and read documentation profusely, and have a working authentication setup, but I wanted to post it to this list and ask one question: is this secure?

There's one hole I'm aware of that I'll explain below, but I want to be sure that my implementation - specifically, my use of init() to ensure the user is authenticated for all actions in the controller - is considered within "best practices". If not, I need to know what I should be doing instead.

The way this works is that there is ONE and only one user in the users table in the database. It's got a username, password, and of course ID - that's it. The password is stored as an MD5 checksum in the password field.

When the "admin" controller is accessed, I want the very first thing that happens to be a check to see if the user that's logged in is authenticated. If not, it should redirect to the login form and terminate immediately. I believe the use of init() takes care of this, but let me know if I'm missing something here. Should I be using __construct instead, for example?

The only hole I can see with this implementation is if somebody gained access to my database, for any reason, and inserted another row into the admin table, they could login and have the same control over this that I do. I'll implement other controls to restrict that of course, but I want to be sure the direction I'm taking here is solid before I get too deep.

Enough BS, here's the code - please let me know what you think.

- Phoenix

AdminController.php:
-----------------
<?php

   class AdminController extends Zend_Controller_Action
   {
public function init()
       {
           $this->view->title = "Admin Controller";
           $this->_helper->layout->setLayout('admin');
// Authentication
           $auth = Zend_Auth::getInstance();
           if(!$auth->hasIdentity()) {
               // User is not authenticated, so return a redirect.
               return $this->_helper->redirector("index", "login");
           }
}

// All my other actions down here, none of which can be accessed without going through init(), right?




LoginController.php
-------------------------
<?php

class LoginController extends Zend_Controller_Action
{
public function indexAction()
   {
       $this->view->form = $this->getForm();
   }
public function getForm()
   {
       require_once(FORMS_PATH.'/loginform.php');
return new LoginForm(array('action' => '/login/process', 'method' => 'post'));
   }

   public function preDispatch()
   {
       if(Zend_Auth::getInstance()->hasIdentity()) {
           if('logout' != $this->getRequest()->getActionName()) {
               $this->_helper->redirector('index', 'admin');
           }
       }
else {
           if('logout' == $this->getRequest()->getActionName()) {
               $this->_helper->redirector('index');
           }
       }
} public function processAction()
   {
       $request = $this->getRequest();
// If this ISN'T a post request, redirect and die
       if(!$request->isPost()) {
           return $this->_helper->redirector('index');
       }
// Retrieve and validate form
       $form = $this->getForm();
       if(!$form->isValid($request->getPost())) {
           // Invalid form entries
           $this->view->form = $form;
           return $this->render('index'); // re-render the login form
       }
// Set up $username and $password
       $username = $form->getValue('username');
       $password = $form->getValue('password');
// Get authentication adapter and check credentials.
       require_once(MODELS_PATH.'/auth.php');
       $adapter = new AuthAdapter($username, $password);
       $auth = Zend_Auth::getInstance();
       $result = $auth->authenticate($adapter);
// Test to see if they're authenticated or not
       if(!$result->isValid()) {
           // NOT authenticated
           $form->setDescription("Your login failed.");
           $this->view->form = $form;
           return $this->render('index');
       }
// If we made it past all the if/return combinations, we're authenticated
       $this->_helper->redirector('index', 'admin');
} public function logoutAction()
   {
       Zend_Auth::getInstance()->clearIdentity();
       $this->_helper->redirector('index', 'index');
   }
}



And finally, my authentication class:  auth.php
-----------------------------------------
<?php

class AuthAdapter implements Zend_Auth_Adapter_Interface
{
   /*
    * Sets username and password for authentication
    */
   public function __construct($username, $password)
   {
       $this->username = $username;
       $this->password = $password;
   }
/*
    * Performs an authentication attempt
    *
* @throws Zend_Auth_Adapter_Exception If authentication cannot be performed
    *
    * @return Zend_Auth_Result
    */
   public function authenticate()
   {
       // set up authentication adapter
       $adapter = new Zend_Auth_Adapter_DbTable($this->getDB());
       $adapter->setTableName('admin');
       $adapter->setIdentityColumn('user');
       $adapter->setCredentialColumn('pass');
// Set the actual credentials themselves
       $adapter->setIdentity($this->username);
       $adapter->setCredential($this->password);
       $adapter->setCredentialTreatment("MD5(?)");
// Perform the authentication and trap the results in an object.
       $result = $adapter->authenticate();
       return $result;
} private function getDB()
   {
       return Zend_Registry::get('db');
   }
}

Reply via email to