Tabla de contenidos
Zend_Auth proporciona una API para la autenticación e
incluye adaptadores de autenticación concretos para escenarios de uso comunes.
A Zend_Auth solo le concierne la autenticación
y no la autorización. La autenticación se define, de manera general,
como la determinación de si una entidad realmente es lo que dice ser (es decir, identificación),
basándose en un conjunto de credenciales. La autorización, el proceso de decidir si se permite
a una entidad acceder a, o realizar operaciones sobre, otras entidades, queda fuera del alcance de
Zend_Auth. Para más información sobre autorización y control de
acceso con Zend Framework, consulte Zend_Acl.
![]() |
Nota |
|---|---|
La clase |
Un adaptador de Zend_Auth se utiliza para autenticar contra un tipo
particular de servicio de autenticación, como LDAP,
RDBMS, o almacenamiento basado en archivos. Es probable que distintos adaptadores
tengan opciones y comportamientos muy diferentes, pero algunas cuestiones básicas son comunes a los
adaptadores de autenticación. Por ejemplo, aceptar credenciales de autenticación (incluyendo una
identidad declarada), realizar consultas contra el servicio de autenticación, y
devolver resultados son comunes a los adaptadores de Zend_Auth.
Cada clase adaptadora de Zend_Auth implementa
Zend_Auth_Adapter_Interface. Esta interfaz define un método,
authenticate(), que una clase adaptadora debe implementar para
realizar una consulta de autenticación. Cada clase adaptadora debe prepararse antes de
llamar a authenticate(). Dicha preparación del adaptador incluye
configurar credenciales (por ejemplo, nombre de usuario y contraseña) y definir valores para
opciones de configuración específicas del adaptador, como los parámetros de conexión a la base de
datos para un adaptador de tabla de base de datos.
A continuación se muestra un ejemplo de adaptador de autenticación que requiere que se establezca un nombre de usuario y una contraseña para la autenticación. Otros detalles, como la forma en que se consulta el servicio de autenticación, se han omitido por brevedad:
class MyAuthAdapter implements Zend_Auth_Adapter_Interface
{
/**
* Sets username and password for authentication
*
* @return void
*/
public function __construct($username, $password)
{
// ...
}
/**
* Performs an authentication attempt
*
* @throws Zend_Auth_Adapter_Exception If authentication cannot
* be performed
* @return Zend_Auth_Result
*/
public function authenticate()
{
// ...
}
}
Como se indica en su docblock, authenticate() debe devolver una
instancia de Zend_Auth_Result (o de una clase derivada de
Zend_Auth_Result). Si por alguna razón resulta imposible realizar
una consulta de autenticación, authenticate() debería
lanzar una excepción que derive de
Zend_Auth_Adapter_Exception.
Los adaptadores de Zend_Auth devuelven una instancia de
Zend_Auth_Result con authenticate() con el
fin de representar los resultados de un intento de autenticación. Los adaptadores rellenan el
objeto Zend_Auth_Result en el momento de la construcción, de manera que los
siguientes cuatro métodos proporcionan un conjunto básico de operaciones orientadas al usuario que son comunes a los
resultados de los adaptadores de Zend_Auth:
isValid()- devuelveTRUEsi y solo si el resultado representa un intento de autenticación exitosogetCode()- devuelve un identificador constante deZend_Auth_Resultpara determinar el tipo de fallo de autenticación o si se ha producido un éxito. Esto puede usarse en situaciones en las que el desarrollador desee distinguir entre varios tipos de resultado de autenticación. Esto permite a los desarrolladores mantener estadísticas detalladas de resultados de autenticación, por ejemplo. Otro uso de esta característica es proporcionar mensajes específicos y personalizados a los usuarios por motivos de usabilidad, aunque se anima a los desarrolladores a considerar los riesgos de proporcionar razones tan detalladas a los usuarios, en lugar de un mensaje general de fallo de autenticación. Para más información, consulte las notas siguientes.getIdentity()- devuelve la identidad del intento de autenticacióngetMessages()- devuelve un array de mensajes relativos a un intento de autenticación fallido
Un desarrollador puede querer ramificar en función del tipo de resultado de autenticación con el fin de realizar operaciones más específicas. Algunas operaciones que los desarrolladores pueden encontrar útiles son bloquear cuentas tras demasiados intentos fallidos de contraseña, marcar una dirección IP tras demasiados intentos con identidades inexistentes, y proporcionar mensajes específicos y personalizados de resultado de autenticación al usuario. Los siguientes códigos de resultado están disponibles:
Zend_Auth_Result::SUCCESS Zend_Auth_Result::FAILURE Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID Zend_Auth_Result::FAILURE_UNCATEGORIZED
El siguiente ejemplo ilustra cómo un desarrollador puede ramificar según el código de resultado:
// inside of AuthController / loginAction
$result = $this->_auth->authenticate($adapter);
switch ($result->getCode()) {
case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
/** do stuff for nonexistent identity **/
break;
case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
/** do stuff for invalid credential **/
break;
case Zend_Auth_Result::SUCCESS:
/** do stuff for successful authentication **/
break;
default:
/** do stuff for other failure **/
break;
}
Autenticar una petición que incluye credenciales de autenticación es útil per se, pero también es importante poder mantener la identidad autenticada sin tener que presentar las credenciales de autenticación en cada petición.
Sin embargo, HTTP es un protocolo sin estado, y por ello se han desarrollado técnicas como las cookies y las sesiones con el fin de facilitar el mantenimiento del estado a través de múltiples peticiones en aplicaciones web del lado del servidor.
Por defecto, Zend_Auth proporciona almacenamiento persistente de la
identidad a partir de un intento de autenticación exitoso usando la sesión de
PHP. Tras un intento de autenticación exitoso,
Zend_Auth::authenticate() almacena la identidad del
resultado de la autenticación en almacenamiento persistente. A menos que se configure de otro modo,
Zend_Auth utiliza una clase de almacenamiento denominada
Zend_Auth_Storage_Session, que, a su vez, utiliza
Zend_Session. En su lugar puede usarse una
clase personalizada proporcionando un objeto que implemente
Zend_Auth_Storage_Interface a
Zend_Auth::setStorage().
![]() |
Nota |
|---|---|
Si el almacenamiento persistente automático de la identidad no es apropiado para un
caso de uso particular, los desarrolladores pueden prescindir de usar
la clase |
Ejemplo 15.1. Modificar el espacio de nombres de la sesión
Zend_Auth_Storage_Session utiliza un espacio de nombres de sesión
'Zend_Auth'. Este espacio de nombres puede sobrescribirse pasando
un valor diferente al constructor de
Zend_Auth_Storage_Session, y este valor se pasa internamente
al constructor de
Zend_Session_Namespace. Esto debería ocurrir antes de que se
intente la autenticación, ya que
Zend_Auth::authenticate() realiza el almacenamiento
automático de la identidad.
// Save a reference to the Singleton instance of Zend_Auth
$auth = Zend_Auth::getInstance();
// Use 'someNamespace' instead of 'Zend_Auth'
$auth->setStorage(new Zend_Auth_Storage_Session('someNamespace'));
/**
* @todo Set up the auth adapter, $authAdapter
*/
// Authenticate, saving the result, and persisting the identity on
// success
$result = $auth->authenticate($authAdapter);
A veces los desarrolladores pueden necesitar usar un mecanismo de almacenamiento de identidad distinto
al proporcionado por Zend_Auth_Storage_Session. Para estos casos
los desarrolladores pueden simplemente implementar Zend_Auth_Storage_Interface
y proporcionar una instancia de la clase a
Zend_Auth::setStorage().
Ejemplo 15.2. Usar una clase de almacenamiento personalizada
Para usar una clase de almacenamiento de persistencia de identidad distinta de
Zend_Auth_Storage_Session, un desarrollador implementa
Zend_Auth_Storage_Interface:
class MyStorage implements Zend_Auth_Storage_Interface
{
/**
* Returns true if and only if storage is empty
*
* @throws Zend_Auth_Storage_Exception If it is impossible to
* determine whether storage
* is empty
* @return boolean
*/
public function isEmpty()
{
/**
* @todo implementation
*/
}
/**
* Returns the contents of storage
*
* Behavior is undefined when storage is empty.
*
* @throws Zend_Auth_Storage_Exception If reading contents from
* storage is impossible
* @return mixed
*/
public function read()
{
/**
* @todo implementation
*/
}
/**
* Writes $contents to storage
*
* @param mixed $contents
* @throws Zend_Auth_Storage_Exception If writing $contents to
* storage is impossible
* @return void
*/
public function write($contents)
{
/**
* @todo implementation
*/
}
/**
* Clears contents from storage
*
* @throws Zend_Auth_Storage_Exception If clearing contents from
* storage is impossible
* @return void
*/
public function clear()
{
/**
* @todo implementation
*/
}
}
Para usar esta clase de almacenamiento personalizada,
Zend_Auth::setStorage() se invoca antes de que se intente
una consulta de autenticación:
// Instruct Zend_Auth to use the custom storage class Zend_Auth::getInstance()->setStorage(new MyStorage()); /** * @todo Set up the auth adapter, $authAdapter */ // Authenticate, saving the result, and persisting the identity on // success $result = Zend_Auth::getInstance()->authenticate($authAdapter);
Existen dos formas de utilizar los adaptadores de Zend_Auth:
indirectamente, a través de
Zend_Auth::authenticate()directamente, a través del método
authenticate()del adaptador
El siguiente ejemplo ilustra cómo usar un adaptador de Zend_Auth
de forma indirecta, mediante el uso de la clase Zend_Auth:
// Get a reference to the singleton instance of Zend_Auth
$auth = Zend_Auth::getInstance();
// Set up the authentication adapter
$authAdapter = new MyAuthAdapter($username, $password);
// Attempt authentication, saving the result
$result = $auth->authenticate($authAdapter);
if (!$result->isValid()) {
// Authentication failed; print the reasons why
foreach ($result->getMessages() as $message) {
echo "$message\n";
}
} else {
// Authentication succeeded; the identity ($username) is stored
// in the session
// $result->getIdentity() === $auth->getIdentity()
// $result->getIdentity() === $username
}
Una vez se ha intentado la autenticación en una petición, como en el ejemplo anterior, resulta sencillo comprobar si existe una identidad correctamente autenticada:
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
// Identity exists; get it
$identity = $auth->getIdentity();
}
Para eliminar una identidad del almacenamiento persistente, simplemente use el método
clearIdentity(). Esto se usaría típicamente para
implementar una operación de "logout" (cierre de sesión) de la aplicación:
Zend_Auth::getInstance()->clearIdentity();
Cuando el uso automático de almacenamiento persistente no es apropiado para un caso de uso
particular, un desarrollador puede simplemente omitir el uso de la clase
Zend_Auth, utilizando directamente una clase adaptadora. El uso directo de una
clase adaptadora implica configurar y preparar un objeto adaptador y luego llamar a su
método authenticate(). Los detalles específicos de cada adaptador se explican
en la documentación de cada adaptador. El siguiente ejemplo utiliza directamente
MyAuthAdapter:
// Set up the authentication adapter
$authAdapter = new MyAuthAdapter($username, $password);
// Attempt authentication, saving the result
$result = $authAdapter->authenticate();
if (!$result->isValid()) {
// Authentication failed; print the reasons why
foreach ($result->getMessages() as $message) {
echo "$message\n";
}
} else {
// Authentication succeeded
// $result->getIdentity() === $username
}
![[Note]](images/note.png)