La posibilidad de ejecutar una acción puede ser restringida a usuarios con ciertos privilegios. Las herramientas proporcionadas por Symfony para este propósito permiten la creación de aplicaciones seguras, en las que los usuarios necesitan estar autenticados antes de acceder a alguna característica o a partes de la aplicación. Añadir esta seguridad a una aplicación requiere dos pasos: declarar los requerimientos de seguridad para cada acción y autenticar a los usuarios con privilegios para que puedan acceder estas acciones seguras.
6.5.1. Restricción de Acceso
Antes de ser ejecutada, cada acción pasa por un filtro especial que verifica si el usuario actual tiene privilegios de acceder a la acción requerida. En Symfony, los privilegios estan compuestos por dos partes:
- Las acciones seguras requieren que los usuarios esten autenticados.
- Las credenciales son privilegios de seguridad agrupados bajo un nombre y que permiten organizar la seguridad en grupos.
Para restringir el acceso a una acción se crea y se edita un archivo de configuración YAML llamado security.yml
en el directorio config/
del módulo. En este archivo, se pueden especificar los requerimientos de seguridad que los usuarios deberán satisfacer para cada acción o para todas (all
) las acciones. El listado 6-23 muestra un ejemplo de security.yml
.
Listado 6-23 - Estableciendo restricciones de acceso, en apps/miaplicacion/modules/mimodulo/config/security.yml
ver:
is_secure: off # Todos los usuarios pueden ejecutar la acción "ver"
modificar:
is_secure: on # La acción "modificar" es sólo para usuarios autenticados
borrar:
is_secure: on # Sólo para usuarios autenticados
credentials: admin # Con credencial "admin"
all:
is_secure: off # off es el valor por defecto
Las acciones no incluyen restricciones de seguridad por defecto, asi que cuando no existe el archivo security.yml
o no se indica ninguna acción en ese archivo, todas las acciones son accesibles por todos los usuarios. Si existe un archivo security.yml
, Syfmony busca por el nombre de la acción y si existe, verifica que se satisfagan los requerimientos de seguridad. Lo que sucede cuando un usuario trata de acceder una acción restringida depende de sus credenciales:
- Si el usuario está autenticado y tiene las credenciales apropiadas, entonces la acción se ejecuta.
- Si el usuario no está autenticado, es redireccionado a la acción de login.
- Si el usuario está autenticado, pero no posee las credenciales apropiadas, será redirigido a la acción segura por defecto, como muestra la figura 6-1.
Las páginas login
y secure
son bastante simples, por lo que seguramente será necesario personalizarlas. Se puede configurar que acciones se ejecutan en caso de no disponer de suficientes privilegios en el archivo settings.yml
de la aplicación cambiando el valor de las propiedades mostradas en el listado 6-24.
Listado 6-24 - Las acciones de seguridad por defecto se definen en apps/miaplicacion/config/settings.yml
all:
.actions:
login_module: default
login_action: login
secure_module: default
secure_action: secure
6.5.2. Otorgando Acceso
Para obtener acceso a áreas restringidas, los usuarios necesitan estar autenticados y/o poseer ciertas credenciales. Puedes extender los privilegios del usuario mediante llamadas a métodos del objeto sfUser
. El estado autenticado se establece con el método setAuthenticated()
y se puede comprobar con el método isAuthenticated()
. El listado 6-25 muestra un ejemplo sencillo de autenticación.
Listado 6-25 - Estableciendo el estado de autenticación del usuario
class miCuentaActions extends sfActions
{
public function executeLogin()
{
if ($this->getRequestParameter('login') == 'valor')
{
$this->getUser()->setAuthenticated(true);
}
}
public function executeLogout()
{
if ($this->getUser()->isAuthenticated())
{
$this->getUser()->setAuthenticated(false);
}
}
}
Las credenciales son un poco más complejas de tratar, ya que se pueden verificar, agregar, quitar y borrar. El listado 6-26 describe los métodos de las credenciales de la clase sfUser
.
Listado 6-26 - Manejando las credenciales del usuario en la acción
class miCuentaActions extends sfActions
{
public function executeEjemploDeCredenciales()
{
$usuario = $this->getUser();
// Agrega una o más credenciales
$usuario->addCredential('parametro');
$usuario->addCredentials('parametro', 'valor');
// Verifica si el usuario tiene una credencial
echo $usuario->hasCredential('parametro'); => true
// Verifica si un usuario tiene una de las credenciales
echo $usuario->hasCredential(array('parametro', 'valor')); => true
// Verifica si el usuario tiene ambas credenciales
echo $usuario->hasCredential(array('parametro', 'valor'), true); => true
// Quitar una credencial
$usuario->removeCredential('parametro');
echo $usuario->hasCredential('parametro'); => false
// Elimina todas las credenciales (útil en el proceso de logout)
$usuario->clearCredentials();
echo $usuario->hasCredential('valor'); => false
}
}
Si el usuario tiene la credencial "parametro"
, entonces ese usuario podrá acceder a las acciones para las cuales el archivo security.yml
requiere esa credencial. Las credenciales se pueden utilizar también para mostrar contenido autenticado en una plantilla, como se muestra en el listado 6-27.
Listado 6-27 - Tratando con credenciales de usuario en una plantilla
<ul>
<li><?php echo link_to('seccion1', 'content/seccion1') ?></li>
<li><?php echo link_to('seccion2', 'content/seccion2') ?></li>
<?php if ($sf_user->hasCredential('seccion3')): ?>
<li><?php echo link_to('seccion3', 'content/seccion3') ?></li>
<?php endif; ?>
</ul>
Y para el estado de autenticación, las credenciales normalmente se dan a los usuarios durante el proceso de login. Este es el motivo por el que el objeto sfUser
normalmente se extiende para añadir métodos de login y de logout, de forma que se pueda establecer el estado de seguridad del usuario de forma centralizada.
Truco Entre los plugins de Symfony, sfGuardPlugin extiende la clase de sesión para facilitar el proceso de login y logout. El Capitulo 17 contiene más información al respecto.
6.5.3. Credenciales Complejas
La sintaxis YAML utilizada en el archivo security.yml
permite restringir el acceso a usuarios que tienen una combinación de credenciales, usando asociaciones de tipo AND y OR. Con estas combinaciones, se pueden definir flujos de trabajo y sistemas de manejo de privilegios muy complejos -- como por ejemplo, un sistema de gestión de contenidos (CMS) cuya parte de gestión sea accesible solo a usuarios con credencial admin
, donde los artículos pueden ser editados solo por usuarios con credenciales de editor
y publicados solo por aquellos que tienen credencial de publisher
. El listado 6-28 muestra este ejemplo.
Listado 6-28 - Sintaxis de combinación de credenciales
editarArticulo:
credentials: [ admin, editor ] # admin AND editor
publicarArticulo:
credentials: [ admin, publisher ] # admin AND publisher
gestionUsuarios:
credentials: [[ admin, superuser ]] # admin OR superuser
Cada vez que se añade un nuevo nivel de corchetes, la lógica cambia entre AND y OR. Así que se pueden crear combinaciones muy complejas de credenciales, como la siguiente:
credentials: [[root, [supplier, [owner, quasiowner]], accounts]]
# root OR (supplier AND (owner OR quasiowner)) OR accounts