TigerZF
🌐Español

12.3. Uso avanzado

12.3.1. Almacenamiento de datos de ACL para persistencia

Zend_Acl fue diseñado de tal manera que no requiere ninguna tecnología de backend en particular, como una base de datos o un servidor de caché, para el almacenamiento de los datos de ACL. Su implementación completa en PHP permite construir herramientas de administración personalizadas sobre Zend_Acl con relativa facilidad y flexibilidad. Muchas situaciones requieren alguna forma de mantenimiento interactivo de la ACL, y Zend_Acl proporciona métodos para configurar y consultar los controles de acceso de una aplicación.

El almacenamiento de los datos de ACL se deja, por lo tanto, como una tarea para el desarrollador, ya que se espera que los casos de uso varíen ampliamente según la situación. Debido a que Zend_Acl es serializable, los objetos ACL pueden serializarse con la función serialize() de PHP, y los resultados pueden almacenarse donde el desarrollador desee, como un archivo, una base de datos o un mecanismo de caché.

12.3.2. Escritura de reglas condicionales de ACL con aserciones

A veces una regla para permitir o denegar el acceso de un rol a un recurso no debe ser absoluta, sino dependiente de varios criterios. Por ejemplo, supongamos que cierto acceso debería permitirse, pero solo entre las 8:00 a.m. y las 5:00 p.m. Otro ejemplo sería denegar el acceso porque una petición proviene de una dirección IP que ha sido marcada como fuente de abuso. Zend_Acl tiene soporte incorporado para implementar reglas basadas en cualquier condición que el desarrollador necesite.

Zend_Acl proporciona soporte para reglas condicionales con Zend_Acl_Assert_Interface. Para usar la interfaz de aserción de reglas, un desarrollador escribe una clase que implementa el método assert() de la interfaz:

class CleanIPAssertion implements Zend_Acl_Assert_Interface
{
    public function assert(Zend_Acl $acl,
                           Zend_Acl_Role_Interface $role = null,
                           Zend_Acl_Resource_Interface $resource = null,
                           $privilege = null)
    {
        return $this->_isCleanIP($_SERVER['REMOTE_ADDR']);
    }

    protected function _isCleanIP($ip)
    {
        // ...
    }
}

Una vez que una clase de aserción está disponible, el desarrollador debe proporcionar una instancia de la clase de aserción al asignar reglas condicionales. Una regla que se crea con una aserción solo se aplica cuando el método de aserción devuelve TRUE.

$acl = new Zend_Acl();
$acl->allow(null, null, null, new CleanIPAssertion());

El código anterior crea una regla condicional de permiso que permite el acceso a todos los privilegios sobre todo por parte de todos, excepto cuando la IP solicitante está en la "lista negra." Si una petición proviene de una IP que no se considera "limpia," entonces la regla de permiso no se aplica. Dado que la regla se aplica a todos los roles, todos los recursos y todos los privilegios, una IP "no limpia" resultaría en una denegación de acceso. Este es un caso especial, sin embargo, y debe entenderse que en todos los demás casos (es decir, cuando se especifica un rol, recurso o privilegio concreto para la regla), una aserción fallida hace que la regla no se aplique, y se utilizarían otras reglas para determinar si el acceso se permite o se deniega.

Al método assert() de un objeto de aserción se le pasa la ACL, el rol, el recurso y el privilegio a los que se aplica la consulta de autorización (es decir, isAllowed()), con el fin de proporcionar un contexto para que la clase de aserción determine sus condiciones cuando sea necesario.