Las próximas versiones de Symfony2 podrían prescindir de la ACL

Las ACL o listas de control de acceso son la forma más granular de otorgar permisos en las aplicaciones Symfony2. Utilizando una ACL es posible indicar si un determinado usuario tiene un determinado permiso sobre un determinado objeto. En teoría las ACL son una solución excelente y han formado parte del componente de seguridad de Symfony desde el principio.

El único problema es que utilizar la ACL de Symfony2 es extremadamente difícil. Observa por ejemplo el código necesario para otorgar el permiso OWNER al usuario $user sobre el objeto $object (además, para que este código funcione es necesario haber actualizado previamente el archivo de configuración security.yml y también hay que crear varias tablas en la base de datos):

$aclProvider = $this->get('security.acl.provider');
$objectIdentity = ObjectIdentity::fromDomainObject($object);
$acl = $aclProvider->createAcl($objectIdentity);
 
$securityContext = $this->get('security.context');
$user = $securityContext->getToken()->getUser();
$securityIdentity = UserSecurityIdentity::fromAccount($user);
 
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
$aclProvider->updateAcl($acl);

A estos problemas hay que añadir la falta casi total de documentación y el abandono del código por parte de su autor, Johannes Schmitt, que asegura que ya no tiene tiempo para esto.

Así que Fabien ha decidido solucionar todos estos problemas de una vez con una propuesta bastante radical: eliminar la ACL del componente de seguridad y pasarla a un nuevo componente, librería o proyecto independiente de Symfony. La discusión generada por este tema tiene muchas opiniones a favor y en contra, pero casi todas ellas coinciden en que de una forma o de otra hay que simplificar drásticamente la ACL para poder utilizarla.

Si se elimina la ACL, la alternativa propuesta consiste en utilizar los security voters, que son mucho más fáciles de crear y mantener. En la aplicación Cupon que usamos como ejemplo en el libro de Symfony2, hemos optado por esa solución. La versión del libro para Symfony 2.3 utiliza un security voter propio en vez de la ACL. Puedes ver el código fuente del cambio en GitHub y muy pronto tendrás la explicación completa en la versión actualizada del libro para Symfony 2.3.

Por último, si finalmente se opta por mantener la ACL simplificándola, ahí va nuestra propuesta sobre cómo podría simplificarse el código anterior a una sola línea de código:

$this->get('security.context')->grant($user, $object, 'OWNER');

Comentarios

  1. Normal, yo me he encontrado en varios proyectos con la posibilidad de usar ACL, y siempre he terminado usando "security voters".

    El problema no solo está en la dificultad de uso y en que te crea varias tablas para algo que se puede solucionar de forma más eficiente de otras maneras. Para mí el mayor problema es la "actualización" de los permisos. Si resulta que le doy permiso de acceso a un grupo/role a un determinado objeto, pero por lo que sea hay un miembro de ese grupo/role que no quiero que tenga acceso, o bien quiero permitir acceso a un usuario a ese objeto, pero no quiero añadirle a ese grupo, la cosa se va volviendo inmanejable, proliferando los grupos/roles solo para definir accesos a un objeto.

    Por ejemplo, un caso que es prácticamente imposible con ACL y sin embargo los "security voters" manejan estupendamente: una red social en la que a las publicaciones pueden tener acceso tus amigos, o todo el mundo, o los que pertenezcan a un grupo determinado. Con ACL tendrías que hacer un role por usuario y cada usuario tener tantos roles como amigos tenga, o grupos participe. Inmanejable. Con security voters solo tienes que implementar una función que compare la "privacidad" del objeto con la relación que ese usuario tiene con el dueño del objeto.

    Miguel Angel Garzón el 27 de agosto de 2013, 12:35:38

  2. A mi me pasó lo mismo en el proyecto anterior a lo que comenta Miguel, al final lo descartamos porque para algo sencillo generaba un nivel de complejidad bastante importante.

    Ahora estoy empezando otro proyecto bastante grande y vemos la necesidad de acl, pero valorando de nuevo, nos vuelve a dar la misma sensación, que en cuantro esto crezca nos va a hacer llorar sangre.

    Echaré un ojo a la versión de security voter de la 2.3 a ver que tal.

    Eso si, lo dije cuando salió 2.0, cuando 2.2/2.3 con el cambio de forms y ahora con esta noticia, la 'manía' de sensio de cambiar las cosas de repente 360º no acaba de convencerme ... Da sensación de ir a salto de mata ...

    Gonzalo González Domínguez el 28 de agosto de 2013, 9:59:23

  3. @Miguel Si no te importa compartir el código 'no crítico' de esta parte creo que nos vendría bien a mucha gente. :)

    Gonzalo González Domínguez el 3 de septiembre de 2013, 9:23:04

  4. Pregunta existencial para el tema security voter. ¿Como controlas derechos en roles no jerárquicos?

    Por ejemplo ROLE_GESTOR deniega y ROLE_COORDINADOR permite. Un usuario con ambos, siendo no jerárquicos los roles, ¿con cual se queda?

    Gonzalo González Domínguez el 5 de septiembre de 2013, 9:56:53

  5. @Gonzalo, en un security voter puedes hacer cualquier cosa y comprobar cualquier tipo de permiso. La clave está en el método vote() al que puedes añadir tanta lógica como necesites. Ver ejemplo

    Javier Eguiluz el 5 de septiembre de 2013, 10:02:34

  6. Justo estoy desgrando el ejemplo de cupon, entiendo entonces que tendré que hacer 'manualmente' en programación que uno de los roles tenga más 'peso' que el otro dentro de vote () ¿no?

    Gonzalo González Domínguez el 5 de septiembre de 2013, 10:54:25

Este artículo ya no permite añadir más comentarios.
¿Por qué? Los artículos cierran sus comentarios automáticamente unos meses después de su publicación para asegurar que estos sigan siendo relevantes.

Publicada el

27 de agosto de 2013

Proyectos Symfony destacados

La plataforma de eCommerce 100% Symfony que rivaliza con Magento y PrestaShop. Ver más

Síguenos en @symfony_es para acceder a las últimas noticias.