Вы должны создать свой собственный Zend_Auth_Adapter. Этот адаптер попытается аутентифицироваться на ваших трех ресурсах и пометит это в частной переменной-члене, чтобы вы могли знать, какие из попыток входа были успешно аутентифицированы.
Чтобы создать свой Auth Adapter, вы можете взять за основу Zend_Auth_Adapter_DbTable.
Итак, в __construct вместо передачи только одного адаптера DbTable можно передать три адаптера, используемых в каждом ресурсе. Вы будете поступать таким образом, только если каждый из них использует разные ресурсы, такие как LDAP, например, или даже другую базу данных, если нет, вы можете передать только один адаптер и установить три разных имени таблицы в параметрах конфигурации.
Вот пример из Zend_Auth_Adapter_DbTable:
/**
* __construct() - Sets configuration options
*
* @param Zend_Db_Adapter_Abstract $zendDb
* @param string $tableName
* @param string $identityColumn
* @param string $credentialColumn
* @param string $credentialTreatment
* @return void
*/
public function __construct(Zend_Db_Adapter_Abstract $zendDb, $tableName = null, $identityColumn = null,
$credentialColumn = null, $credentialTreatment = null)
{
$this->_zendDb = $zendDb;
// Here you can set three table names instead of one
if (null !== $tableName) {
$this->setTableName($tableName);
}
if (null !== $identityColumn) {
$this->setIdentityColumn($identityColumn);
}
if (null !== $credentialColumn) {
$this->setCredentialColumn($credentialColumn);
}
if (null !== $credentialTreatment) {
$this->setCredentialTreatment($credentialTreatment);
}
}
Метод ниже, из Zend_Auth_Adapter_DbTable, пытается аутентифицироваться в одной таблице, вы можете изменить его, чтобы попробовать в трех таблицах, и для каждой, когда вы добьетесь успеха, вы установите это как флаг в частной переменной-члене. Что-то вроде $result['group1'] = 1; Вы установите 1 для каждой успешной попытки входа в систему.
/**
* authenticate() - defined by Zend_Auth_Adapter_Interface. This method is called to
* attempt an authentication. Previous to this call, this adapter would have already
* been configured with all necessary information to successfully connect to a database
* table and attempt to find a record matching the provided identity.
*
* @throws Zend_Auth_Adapter_Exception if answering the authentication query is impossible
* @return Zend_Auth_Result
*/
public function authenticate()
{
$this->_authenticateSetup();
$dbSelect = $this->_authenticateCreateSelect();
$resultIdentities = $this->_authenticateQuerySelect($dbSelect);
if ( ($authResult = $this->_authenticateValidateResultset($resultIdentities)) instanceof Zend_Auth_Result) {
return $authResult;
}
$authResult = $this->_authenticateValidateResult(array_shift($resultIdentities));
return $authResult;
}
Вы вернете действительный результат $authresult только в том случае, если одна из трех попыток входа в систему была успешно аутентифицирована.
Теперь в вашем контроллере, после попытки входа в систему:
public function loginAction()
{
$form = new Admin_Form_Login();
if($this->getRequest()->isPost())
{
$formData = $this->_request->getPost();
if($form->isValid($formData))
{
$authAdapter = $this->getAuthAdapter();
$authAdapter->setIdentity($form->getValue('user'))
->setCredential($form->getValue('password'));
$result = $authAdapter->authenticate();
if($result->isValid())
{
$identity = $authAdapter->getResult();
Zend_Auth::getInstance()->getStorage()->write($identity);
// redirect here
}
}
}
$this->view->form = $form;
}
private function getAuthAdapter()
{
$authAdapter = new MyAuthAdapter(Zend_Db_Table::getDefaultAdapter());
// Here the three tables
$authAdapter->setTableName(array('users','users2','users3'))
->setIdentityColumn('user')
->setCredentialColumn('password')
->setCredentialTreatment('MD5(?)');
return $authAdapter;
}
Ключевым моментом здесь является строка ниже, которая будет реализована в вашем пользовательском адаптере аутентификации:
$identity = $authAdapter->getResult();
За основу можно взять вот такую форму Zend_Auth_Adapter_DbTable:
/**
* getResultRowObject() - Returns the result row as a stdClass object
*
* @param string|array $returnColumns
* @param string|array $omitColumns
* @return stdClass|boolean
*/
public function getResultRowObject($returnColumns = null, $omitColumns = null)
{
// ...
}
Это возвращает строку, соответствующую попытке входа в систему при успешной аутентификации. Итак, вы создадите свой метод getResult(), который может возвращать эту строку, а также флаги $this->result['groupX']. Что-то типа:
public function authenticate()
{
// Perform the query for table 1 here and if ok:
$this->result = $row->toArrray(); // Here you can get the table result of just one table or even merge all in one array if necessary
$this->result['group1'] = 1;
// and so on...
$this->result['group2'] = 1;
// ...
$this->result['group3'] = 1;
// Else you will set all to 0 and return a fail result
}
public function getResult()
{
return $this->result;
}
В конце концов, вы можете использовать Zend_Acl, чтобы управлять своими представлениями и другими действиями. Поскольку у вас будут флаги в Zend Auth Storage, вы можете использовать than в качестве ролей:
$this->addRole(new Zend_Acl_Role($row['group1']));
Вот некоторые ресурсы:
http://framework.zend.com/manual/en/zend.auth.introduction.html
http://zendguru.wordpress.com/2008/11/06/zend-framework-auth-with-examples/
http://alex-tech-adventures.com/development/zend-framework/61-zendauth-and-zendform.html
http://alex-tech-adventures.com/development/zend-framework/62-allocation-resources-and-permissions-with-zendacl.html
http://alex-tech-adventures.com/development/zend-framework/68-zendregistry-and-authentication-improvement.html
person
Keyne Viana
schedule
04.08.2010