2012-03-11 9 views
12

Me gustaría escuchar algunas ideas sobre la mejor manera de optimizar nuestro esquema para lograr lo siguiente.La mejor forma de administrar permisos de objeto de usuario/grupo con Symfony2

Tenemos una serie de objetos/entradas db (eventos, lugares, etc.) algunos de los cuales tienen niños objetos (que significa aplicar los mismos permisos - imágenes, Metas, etc.)

Los usuarios pueden pertenecer a grupos de manera matriz objetos tales como eventos, lugares pueden ser editables/visibles por todos, solo grupos, solo un usuario.

Actualmente tenemos un usuario, un grupo de usuarios y una tabla de grupos para administrar usuarios y grupos.

Cada objeto principal como lugares como una columna para user_id y group_id.

Funciona bien (en Symfony 1.4) pero es complicado - cada consulta para cualquier cosa tiene que hacer combinaciones complejas para obtener posibles grupos, etc ... Nos gustaría encontrar una manera más simple.

Estaba realmente entusiasmado con el componente Sf2 ACL, pero una y otra vez me han dicho que no debería usarlo para encontrar objetos que un usuario pueda administrar, sino que debería usar ACL para saber si un usuario está autorizado para administrar sus propios objetos (no parece muy útil, pero lo que sea).

Todos los intentos alternativos en línea que encontré para hacer esto dicen que sacar todos los objetos de db luego filtrar por ACL - es lindo para un sitio de mamá y papá - no va a pasar con un millón de objetos.

Entonces ... Me encantaría escuchar ideas sobre cómo podríamos hacer esto - también estamos abiertos a dejar Symfony por algo que tenga una solución de ACL escalable pero que no haya encontrado nada hasta el momento (php o ruby) abierto a eso también, aunque nos encantaría seguir usando Sf. Tenga en cuenta que tenemos la intención de utilizar MongoDB en caso de que importe.

Respuesta

11

Por lo que entiendo, la ACL se utiliza para dar acceso a un objeto específico a una persona específica para escenarios especiales. Lo que está describiendo es más genérico, pero simplemente se desvía de lo que Symfony2 describe para la seguridad (esta persona tiene un rol de "administrador", pero solo para los objetos contenidos en un grupo en particular).

Las ACL no se deben usar para almacenar un montón de cosas, ya que revisarlas puede ser costoso si se vuelve demasiado grande. Por lo tanto, arrojando un montón de cosas aquí de forma predeterminada cuando se agregan nuevos usuarios, o incluso cuando se agregan nuevos objetos en un grupo (si usa la ACL, tendría que agregar una entrada a cada persona en el grupo cada vez que cree un nuevo objeto), va a estar gravando el rendimiento después de un tiempo ...

Actualmente estoy investigando la posibilidad de usar Symfony2 para una aplicación web, pero también estoy chocando con esta seguridad, ya que tenemos una necesidad similar. No soy un experto en Symfony2, pero por lo que he visto en a, es posible que tenga algunas opciones:

  1. Crear un votante para manejar esto. Los votantes le permiten verificar los tokens de autorización y devolver si se concede o deniega el acceso en función de cómo lo procese. Por lo tanto, podría crear un votante personalizado que verifique el grupo de un usuario e intente hacer coincidirlo con el grupo bajo el que se encuentra el objeto. Si es así, devuelva ACCESS_GRANTED, de lo contrario ACCESS_DENIED, o ACCESS_ABSTAIN si el votante no es válido para la verificación actual. EDITAR: Aquí hay un enlace al libro de cocina Symfony2 para votantes:

  2. También podría interesarle investigar en la interfaz SecurityContext. Esto proporciona el método "isGranted()" que trata de determinar el acceso a los objetos.Si los votantes no son suficientes, es posible que tenga que seguir la ruta de creación de una nueva clase SecurityContext; Creo que esto sería un poco más complicado sin embargo.

Como dije, no soy profesional, y no tengo una solución; Estas son solo algunas direcciones que estoy investigando para tratar de resolver (lo que siento es) un problema similar. Espero que esto ayude un poco.

1

Ha pasado un tiempo desde que publiqué mi respuesta original a esto, pero quería seguir con otra solución, una que estamos usando actualmente.

Mientras que Symfony da una capa de seguridad/ACL para usar, usted no tiene tiene para usarlo, o al menos completamente.

en casi cualquier punto en el tiempo en el código, se puede tirar un Symfony\Component\Security\Core\Exception\AccessDeniedException la capa de seguridad y de la voluntad "patada en" y manejarlo para usted, como redirigir a los usuarios a una página de inicio de sesión, etc.

Algunos de esta interacción puede requerir una configuración de firewall un poco más avanzada para funcionar exactamente como usted lo desee.

Para resumir, mientras que Symfony proporciona algunos mecanismos y características excelentes para ayudar a construir ACL, no tiene que trabajar para adaptar sus datos y procesos a lo que han definido.

Para nuestro sistema como ejemplo, tenemos cuentas, roles y grupos en nuestro sistema (junto con los permisos). También dividimos secciones de datos en Departamentos también. Si bien los usuarios pueden tener Roles y Permisos de nivel global, también pueden tener acceso específico del Departamento. Esta configuración se realizó utilizando las funciones integradas de ACL de Symfony y las herramientas de control de acceso casi inutilizables (lo que no significa que sus herramientas sean inútiles, de hecho son geniales, simplemente no se ajustan a nuestro caso de uso). Por lo tanto, creamos nuestro propio servicio (que utiliza algunas consultas ajustadas) donde pasamos los datos relevantes relativos a un cheque y arroja el Symfony\Component\Security\Core\Exception\AccessDeniedException apropiado cuando falla una verificación.

Cuestiones relacionadas