2012-06-11 9 views
2

Я недавно начал использовать Zend Framework, и я все еще довольно используется для session_start и присвоения переменных в определенных имен сессии (т.е. $ _SESSION [ «имя пользователя»] == $ имя пользователя)Как сохранить и изменить идентификатор сеанса Zend_Auth?

Пытаюсь чтобы выяснить, как сделать что-то подобное в Zend. В настоящий момент мой скрипт аутентификации проверяет учетные данные с помощью LDAP на моем сервере AD и, в случае успеха, аутентифицирует пользователя.

Я хочу создать скрипт, который позволит администратору легко «вводить» чужую сессию. Допустим, у admin1 был активный сеанс и он захотел переключиться на сеанс user1. Обычно я бы просто изменил переменную $ _SESSION ['username'] и эффективно изменил идентификатор пользователя, вошедшего в систему.

Но с Zend я не совсем уверен, как изменить информацию о сеансе. Для чего это стоит, вот мой сценарий аутентификации:

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 
    } 
} 

Есть ли способ сделать то, что я описал? Спасибо за любые предложения.

ответ

2

С учетом вашего кода результат аутентификации хранится в сеансе PHP через объект Zend_Auth_Storage_Session.

Вызов Zend_Auth::getIdentity() получает доступ к хранилищу и возвращает результат, если он не пуст. Аналогично, вы можете изменить сохраненный идентификатор, получив доступ к базовому хранилищу и изменив его значение. Фактическая идентификация, хранящаяся в результате аутентификации с помощью Zend_Auth_Adapter_Ldap, представляет собой просто строковое значение, представляющее имя пользователя LDAP.

Для эффективного изменения зарегистрированного пользователя, вы можете сделать:

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

Это предполагает поведение по умолчанию, которое должно быть на месте данного кода.

Что я делаю в своих приложениях после успешной проверки подлинности, это создать новый объект некоторой модели пользователя и записать его на сеанс Zend_Auth, чтобы у меня было больше информации о пользователе, доступном в каждом сеансе, поэтому вы должны знать что разные вещи могут быть в хранилище в зависимости от приложения.

Это то, что я делаю, например:

$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); 
} 

Теперь в любом месте в моем приложении я называю Zend_Auth::getInstance()->getIdentity() я получить обратно Application_Model_UserSession объект, а не строки; но я отвлекся.

Информация, которая должна помочь вам:

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

Zend_Auth::getInstance()->getStorage()->write($newUser); 
+0

Вы сударь, спасатель. Это сделал трюк. Теперь у меня есть несколько связанный, но несвязанный вопрос. Текущий результат объекта $ user - \ MYDIRECTORY \ имя пользователя. Значением \ MYDIRECTORY \ является то, что определено в моем файле application.ini как 'ldap.server2.accountDomainNameShort' Есть ли причина, по которой это тянет? –

+0

Префикс специфичен для адаптера LDAP, я заметил, что HTTP auth делает что-то похожее на область. Является ли это доменом, который становится предпочтительным? Я думаю, что это так, чтобы вы могли оглянуться назад и узнать, откуда они были аутентифицированы. Вероятно, вам нужно будет только добавить, что при изменении сеанса вручную, если ваше приложение каким-то образом опирается на него, в противном случае вы можете спокойно опустить его. – drew010

Смежные вопросы