Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Seguridad y Autorización en Symfony 2

9 de octubre de 2013

Hola,

La verdad soy nuevo en este tema de Symfony2, y estoy realmente complicado con dos puntos. Estos son básicos, pero al ser principiante necesito algo de ayuda.

Verán, estoy desarrollando una página, donde dos son los tipos usuarios que pueden acceder a ella. Uno es el usuario Trabajador de la empresa X, y otro es el Cliente de la empresa X.

Entonces no consigo controlar el acceso al sistema de ambos usuario. Si bien Symfony trata el tema del ingreso con los formularios de acceso y el archivo security.yml(php,xml), no consigo que mi usuario Trabajador pueda acceder a ciertas páginas (las cuales son distintas a las del otro usuario). Porque no conseguí entender el tema ^/admin/* de la configuración en el archivo security.yml.

Segundo, como puedo hacer que mi usuario Trabajador sea dirigido a una página de inicio distinta a la del usuario Cliente?

Ante todo muchas gracias


Respuestas

#1

@Enzo_B16, al principio es normal perderse un poco con el sistema de seguridad de Symfony2, ya que es uno de sus componentes más complejos. Lo primero que debes hacer es comprender bien la estructura del archivo security.yml, que está dividida en cuatro partes:

# app/config/security.yml
security:
    firewalls:
        # aquí configuras las partes de la aplicación que se protegen

    access_control:
        # aquí configuras qué usuarios pueden acceder a cada parte del sitio

    providers:
        # aquí configuras de dónde salen los usuarios de la aplicación

    encoders:
        # aquí configuras cómo se codifican las contraseñas de cada usuario

En tu caso, vamos a suponer que el sitio web tiene tres partes diferentes:

  • Parte pública, a la que puede entrar cualquiera.
  • Parte privada, a la que sólo pueden entrar los clientes (usuarios de tipo Cliente)
  • Parte de administración, a la que sólo pueden entrar los propios trabajadores de la empresa (usuarios de tipo Trabajador).

Para simplificar el ejemplo vamos a suponer que la parte privada es cualquier página cuya URL empiece por /privado/ y que la parte de administración es cualquier página cuya URL empiece por /admin.

Como tu sitio tiene tres secciones diferentes a las que pueden acceder diferentes tipos de usuarios, tienes que definir tres firewalls (el orden en el que los defines es extremadamente importante):

# app/config/security.yml
security:
    firewalls:
        administracion:
            # ...
        privado:
            # ...
        publico:
            # ...

    access_control:
        # ...

    providers:
        # ...

    encoders:
        # ...

Para simplificar esta respuesta, vamos a suponer que en la parte privada y de administración se utiliza un formulario para pedir el login + contraseña a los usuarios:

# app/config/security.yml
security:
    firewalls:
        administracion:
            pattern:        ^/admin
            provider:       trabajadores
            anonymous:      ~
            form_login:
                login_path: /admin/login
                check_path: /admin/login_check
            logout:
                path:       /admin/logout
                target:     /admin

        privado:
            pattern:        ^/privado
            provider:       clientes
            anonymous:      ~
            form_login:
                login_path: /privado/login
                check_path: /privado/login_check
            logout:
                path:       /privado/logout
                target:     /privado

        publico:
            pattern:        ^/*
            anonymous:      ~

    access_control:
        # ...

    providers:
        trabajadores:
            entity: { class: Acme\AdminBundle\Entity\Trabajador, property: login }
        clientes:
            entity: { class: Acme\ClienteBundle\Entity\Cliente, property: email }

    encoders:
        # ...

Una de las opciones más difíciles de entender de la configuración anterior es la opción anonymous: ~, que permite el acceso a los usuarios anónimos a las URL que protege ese firewall. Si no la añades, ningún usuario anónimo podrá acceder a ninguna URL protegida por esos firewalls. Por tanto, tampoco podrá acceder al formulario de login que se encuentra bajo ese firewall. Así que añadir esta opción no significa que los usuarios anónimos podrán acceder a cualquier URL, ya que esto se controla con la opción access_control que se explica a continuación.

Con todo esto, lo único que te falta es indicar qué usuarios pueden acceder a cada sección del sitio web. Para ello tienes que configurar la opción access_control añadiendo reglas de acceso (de nuevo el orden de estas reglas es extremadamente importante):

# app/config/security.yml
security:
    firewalls:
        # ...

    access_control:
        - { path: ^/privado/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/privado/*,     roles: ROLE_CLIENTE }
        - { path: ^/admin/login,   roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/*,       roles: ROLE_TRABAJADOR }

    providers:
        # ...

    encoders:
        # ...

Ya sólo te faltaría asignar los roles ROLE_CLIENTE y ROLE_TRABAJADOR a cada una de las entidades de los clientes. El componente de seguridad tiene muchísimas otras opciones y funcionalidades. Así que te recomiendo que te leas detenidamente el capítulo sobre seguridad del libro oficial de Symfony2 y también que le eches un vistazo a esta presentación sobre seguridad que impartió Joan Teixidó en la última conferencia deSymfony.

Respecto a la pregunta sobre redirigir a los usuarios a diferentes páginas en función del tipo de usuario, no es algo sencillo y requiere del uso de los eventos de Symfony2. Aquí puedes ver un ejemplo real de cómo se hace: LoginListener.php

@javiereguiluz

9 octubre 2013, 9:07
#2

Excelente explicación.... Muchas Gracias

@Enzo_B16

14 octubre 2013, 7:52