Ver índice de contenidos del libro

13.8. Controlando el acceso

Ahora que ya has definido a los usuarios de la aplicación y sus roles, puedes utilizar un mecanismo de autorización más avanzado que definir patrones de rutas.

13.8.1. Controlando el acceso en los controladores

Proteger tu aplicación en base a patrones de URLs es muy sencillo, pero en muchos casos no tiene la granularidad suficiente. Por eso, si lo necesitas también puedes forzar la autorización dentro de cualquier controlador:

// ...
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
 
public function helloAction($name)
{
    if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
        throw new AccessDeniedException();
    }
 
    // ...
}

Nota Si utilizas el método isGranted() en el controlador asociado a una página cuya URL no se encuentre protegida por un firewall, Symfony lanzará una excepción. Como ya se explicó anteriormente, casi siempre es buena idea tener un firewall principal que cubra todas las URL de la aplicación.

Si lo prefieres, también puedes instalar el bundle opcional JMSSecurityExtraBundle para controlar el acceso a los controladores mediante anotaciones:

// ...
use JMS\SecurityExtraBundle\Annotation\Secure;
 
/**
 * @Secure(roles="ROLE_ADMIN")
 */
public function helloAction($name)
{
    // ...
}

13.8.2. Controlando el acceso en otros servicios

Aplicando una estrategia similar a la explicada en la sección anterior para los controladores, puedes proteger cualquier otro recurso de Symfony. Si por ejemplo dispones de un servicio que envía emails de parte de un usuario a otro usuario, puedes restringir el uso de esta clase a aquellos usuarios que tengan un role específico.

Consulta el artículo How to secure any Service or Method in your Application para obtener más información sobre cómo utilizar el componente de seguridad para proteger diferentes métodos y servicios de tu aplicación.

13.8.3. Controlando el acceso en las plantillas

Si quieres comprobar los roles de un usuario dentro de una plantilla, utiliza el helper is_granted():

{% if is_granted('ROLE_ADMIN') %}
    <a href="...">Delete</a>
{% endif %}
<?php if ($view['security']->isGranted('ROLE_ADMIN')): ?>
    <a href="...">Delete</a>
<?php endif; ?>

Nota Si utilizas esta función en una plantilla asociada a una URL que no está protegida por un firewall, se mostrará una excepción. Por eso es una buena idea definir un firewall que proteja todas las URL de la aplicación (como ya se explicó al principio de este capítulo).

13.8.4. Listas de control de acceso (ACL)

Imagina que has desarrollado un sistema de blog donde los usuarios pueden comentar tus artículos. Además, quieres que los usuarios puedan modificar sus propios comentarios pero no los de otros usuarios. Por último, quieres que el usuario admin pueda modificar cualquier comentario.

El componente de seguridad incluye un sistema de listas de control de acceso (ACL) que puedes utilizar cuando necesites controlar el acceso a las instancias de un objeto. Sin ACL puedes proteger tu sistema para que sólo determinados usuarios puedan editar los comentarios del blog en general. Pero con ACL puedes restringir o permitir el acceso comentario por comentario.

Para más información, consulta el artículo How to use Access Control Lists (ACLs).