Ver índice de contenidos del libro

13.2. Cómo funciona la seguridad: autenticación y autorización 

El sistema de seguridad de Symfony se basa en identificar primero al usuario (autenticación) y comprobando después si ese usuario tiene acceso al recurso solicitado (autorización).

13.2.1. Firewalls (autenticación)

El sistema de seguridad de Symfony se activa cuando un usuario hace una petición a una URL que está protegida por un firewall o cortafuegos. El trabajo del firewall consiste en determinar si el usuario necesita estar autenticado, y si lo necesita, enviar una respuesta al usuario para iniciar el proceso de autenticación.

Un firewall se activa cuando la URL de una petición entrante concuerda con el valor de su opción de configuración pattern. En este ejemplo el valor de pattern (^/) concuerda con cualquier petición entrante. No obstante, el hecho de que el firewall esté activado no significa que el navegador muestra la caja de login+contraseña para todas las URL. Los usuarios pueden acceder por ejemplo a /foo sin que la aplicación les pida que se autentiquen.

Accediendo a una URL no restringida

Figura 13.2 Accediendo a una URL no restringida

Este funcionamiento es posible en primer lugar porque el firewall permite el acceso a los usuarios anónimos debido a la opción de configuración anonymous. En otras palabras, el firewall no exige que todos los usuarios se autentiquen nada más acceder a la aplicación. Y como en la configuración de la sección access_control no se indica que los usuarios deban tener ningún role especial para acceder a /foo la petición se procesa sin requerir al usuario que se autentique.

Si eliminas la opción anonymous, el efecto es que ahora el firewall pide autenticación a cualquier usuario que solicite cualquier recurso.

13.2.2. Control de acceso (autorización)

Siguiendo con el mismo ejemplo, si un usuario solicita /admin/foo, la aplicación se comporta de manera diferente. Esto es debido a la configuración de la sección access_control, que indica que cualquier URL que coincida con la expresión regular ^/admin (es decir, la URL /admin o cualquier otra URL que coincida con /admin/*) requiere el rol ROLE_ADMIN. Los roles son la clave del sistema de autorización: el usuario puede acceder a /admin/foo sólo si cuenta con el rol ROLE_ADMIN.

Denegando el acceso a una URL protegida

Figura 13.3 Denegando el acceso a una URL protegida

Al igual que sucedía anteriormente, cuando el usuario realiza su petición, el firewall no solicita ningún tipo de identificación. Sin embargo, en cuanto la capa de control de acceso deniega el acceso al usuario (porque los usuarios anónimos no cuentan con el rol ROLE_ADMIN), el firewall toma el control de la aplicación e inicia el proceso de autenticación.

El proceso de autenticación depende del mecanismo de autenticación que utilices. Si estás utilizando por ejemplo el método de autenticación con formulario de acceso, el usuario será redirigido a la página de inicio de sesión. Si estás utilizando la autenticación HTTP, se enviará al usuario una respuesta con código de estado HTTP 401 para que el usuario vea el cuadro de diálogo de login y contraseña.

Ahora el usuario tiene la oportunidad de enviar sus credenciales a la aplicación. Si estas credenciales son válidas, se reintenta la petición original.

Denegando el acceso a un usuario sin la autorización adecuada

Figura 13.4 Denegando el acceso a un usuario sin la autorización adecuada

En este ejemplo, el usuario ryan se autentica correctamente con el firewall. Pero como ryan no cuenta con el rol ROLE_ADMIN, se le sigue negando el acceso a /admin/foo. En la práctica esto significa que ryan verá un mensaje indicándole que se le ha denegado el acceso.

Truco Cuando Symfony niega el acceso al usuario, se muestra una pantalla de error y la respuesta enviada contiene un código de estado HTTP 403 (Forbidden). Puedes personalizar el aspecto y el contenido de las páginas de error y de acceso denegado siguiendo las instrucciones del artículo How to customize Error Pages.

Por último, si el usuario admin solicita /admin/foo, se lleva a cabo un proceso similar, excepto que ahora, después de haberse autenticado, la capa de control de acceso permitirá pasar a la petición:

Accediendo a un recurso protegido

Figura 13.5 Accediendo a un recurso protegido

El flujo de la petición cuando un usuario solicita un recurso protegido es sencillo, pero increíblemente flexible. Como verás más adelante, la autenticación se puede realizar de varias maneras, desde el típico formulario de acceso hasta los certificados X.509 o mediante Twitter. Independientemente del método de autenticación, el flujo de la petición siempre es el mismo:

  1. Un usuario accede a un recurso protegido.
  2. La aplicación redirige al usuario al formulario de acceso.
  3. El usuario presenta sus credenciales (por ejemplo nombre de usuario/contraseña).
  4. El firewall autentica al usuario.
  5. El usuario intenta de nuevo la petición original ahora que ya está autenticado.

Nota El proceso exacto depende realmente del mecanismo de autenticación que utilices. En la autenticación vía formulario, el usuario envía sus credenciales a una URL que procesa el formulario (por ejemplo /login_check) y luego es redirigido a la dirección solicitada originalmente (por ejemplo /admin/foo).

En la autenticación HTTP, el usuario envía sus credenciales directamente a la URL original (por ejemplo /admin/foo) y luego la página se devuelve al usuario en la misma petición (es decir, sin redirección).

Estas pequeñas diferencias no afectan realmente a la filosofía de funcionamiento del mecanismo de seguridad, pero es bueno tenerlas presentes.

Truco Más adelante se explica cómo proteger "cualquier cosa" en Symfony2, incluyendo controladores, objetos e incluso métodos PHP.