Как бы я глобально защитил все мои контроллеры (кроме моего контроллера входа), чтобы обеспечить мое приложение безопасным во всех точках (без скрытого бэкдора на вызовы ajax и т. Д.). Я думал, что могу поместить его в свой файл начальной загрузки, но это не так? Я пытаюсь не добавлять код к каждому контроллеру.
Предложения?
edit : это дополнение к ответу @singles.
Вы должны понимать, что есть две разные вещи. Auth и Acl . Auth сообщает вам, кто является пользователем, и вы можете, например, перенаправить пользователя, не имеющего Auth, в контроллер входа в систему и установить идентификатор авторизации после входа в систему. то система Acl принимает решения «да / нет» на основе данных Auth (может быть идентификатором пользователя или является ролью, хранящейся в хранилище Auth.
В хорошем решении нужно иметь 2 плагины контроллеров (зарегистрированных в хорошем порядке в бутстрапе, Auth then Acl). Если вы не используете плагины контроллера, вам нужно будет вызвать проверку Acl в каждом контроллере, когда это необходимо. Если вам это всегда нужно, используйте плагины.
Внедрите preDispatch()
в плагин Auth, чтобы установить, например, анонимную идентификацию, если у вас нет возврата идентификатора из Zend_Auth. Это фрагмент кода реального:
public function preDispatch(Zend_Controller_Request_Abstract $request) { $module = $request->getModuleName(); $controller = $request->getControllerName(); $action = $request->getActionName(); $auth = Zend_Auth::getInstance(); if (!$auth->hasIdentity()) { // set a default anonymous identity $auth->getStorage()->write(array('name' => 'anonymous','role' => 1,)); } (...)
А для плагина контроллера Acl задача также находится в preDispatch()
. Вы можете запустить проверку acl для каждого запрошенного URL-адреса (так что для каждого пользовательского запроса, даже ajax). Вот частичный фрагмент, так что это просто пример того, как вы могли бы обрабатывать вещи:
public function preDispatch(Zend_Controller_Request_Abstract $request) { $controller = $request->controller; $module = $request->module; $action = $request->action; // here you should code something nice retrieving you Zend_Acl object // with some caching options maybe, building roles, ressources, etc $this->_acl = $this->getAcl(); if (!$this->_acl->isCurrentUserAllowed($module,'see')) { $auth = Zend_Auth::getInstance(); $identity = $auth->hasIdentity('identity')? $auth->getIdentity() : null; if(isset($identity)) { if($identity['name'] == 'anonymous') { // WARNING: avoid infinite redirect loops on login page if (!($request->getControllerName() == 'login' && $request->getActionName()=='login' && $request->getModuleName() == 'default')) { $request->setControllerName('login') ->setActionName('login') ->setModuleName('default'); return; (...)
вpublic function preDispatch(Zend_Controller_Request_Abstract $request) { $controller = $request->controller; $module = $request->module; $action = $request->action; // here you should code something nice retrieving you Zend_Acl object // with some caching options maybe, building roles, ressources, etc $this->_acl = $this->getAcl(); if (!$this->_acl->isCurrentUserAllowed($module,'see')) { $auth = Zend_Auth::getInstance(); $identity = $auth->hasIdentity('identity')? $auth->getIdentity() : null; if(isset($identity)) { if($identity['name'] == 'anonymous') { // WARNING: avoid infinite redirect loops on login page if (!($request->getControllerName() == 'login' && $request->getActionName()=='login' && $request->getModuleName() == 'default')) { $request->setControllerName('login') ->setActionName('login') ->setModuleName('default'); return; (...)
поpublic function preDispatch(Zend_Controller_Request_Abstract $request) { $controller = $request->controller; $module = $request->module; $action = $request->action; // here you should code something nice retrieving you Zend_Acl object // with some caching options maybe, building roles, ressources, etc $this->_acl = $this->getAcl(); if (!$this->_acl->isCurrentUserAllowed($module,'see')) { $auth = Zend_Auth::getInstance(); $identity = $auth->hasIdentity('identity')? $auth->getIdentity() : null; if(isset($identity)) { if($identity['name'] == 'anonymous') { // WARNING: avoid infinite redirect loops on login page if (!($request->getControllerName() == 'login' && $request->getActionName()=='login' && $request->getModuleName() == 'default')) { $request->setControllerName('login') ->setActionName('login') ->setModuleName('default'); return; (...)
и в этой системе последней важной частью является LoginController, где в случае успешного входа в систему вы должны запустить идентификационную запись:
(...) $auth = Zend_Auth::getInstance(); Zend_Session::regenerateId(); $storage = $auth->getStorage(); $rowobject = $authAdapter->getResultRowObject(null,'passwd'); $storage->write((array)$rowobject); (...)
Вы должны написать плагин ACL для этого и зарегистрировать его на переднем контроллере. Если вы реализуете такую функциональность, как плагин, вы будете иметь гибкость, чтобы использовать ее в своем следующем приложении – без необходимости расширения каждого контроллера с вашего настраиваемого контроллера.
Ресурсы:
1. Плагины переднего контроллера в Zend Framework – как работают плагины в ZF
2. Пример сценария Zend_Acl / Zend_Auth – одна из многих возможных реализаций плагина ACL.
3. Google – и много других ресурсов
Ну, у вас должна быть точка входа в вашу систему 🙂
Это может быть достигнуто путем расширения Zend_Controller_Action, скажем:
abstract class MyController extends Zend_Controller_Action { public function preDispatch(){ // do the logic } }
И теперь каждому из ваших контроллеров нужно только расширить MyController, и вы в безопасности.
То, как я сделал это в одной реализации, было создание файла с именем Auth.php в моем пути к приложению. Затем я открыл каждый контроллер, который хотел защитить, и добавил строку
include_once APPLICATION_PATH . '/Auth.php';
к методу init () перед вызовом parent :: init ().
Что касается самого файла Auth.php, он в основном использует Zend_Auth для аутентификации. При успехе я бы сохранил личность пользователя для последующего использования в приложении
$this->view->assign('myIdentity', Zend_Auth::getInstance()->getIdentity());
В случае сбоя я бы перенаправил страницу входа и передал некоторые параметры, чтобы страница входа в систему знала, куда мне отправить сообщение после входа в систему.
Это не изящное решение, но оно надежное и относительно быстрое и простое в использовании.