Nuevo en Symfony 5.1: Nuevo sistema de seguridad

Symfony 5.1 incluirá un nuevo sistema de seguridad como una de sus novedades principales. Después de muchos meses de planificación, discusiones y trabajo duro, conseguimos finalizarlo a tiempo para Symfony 5.1 como funcionalidad experimental.

Las principales diferencias con respecto al sistema anterior son:

1) Eliminado todo lo que no sean Guards

En el nuevo sistema de seguridad solamente hay un listener que pasa la petición a un authenticator manager gestionado por Symfony y que gestiona la sesión, almacena el token de seguridad, implementa la funcionalidad No cerrar sesión, etc.

Todo está relacionado con un único concepto: authenticators. Esto simplifica el código interno del componente de seguridad y hace que todo sea mucho más fácil de entender para los programadores/as.

2) Uso extensivo de eventos

El componente de seguridad no usaba eventos para extender alguna de sus funcionalidades. El nuevo sistema corrige esto y se basa en tres eventos:

  • CheckPassportEvent, es el evento principal y comprueba la validez de las credenciales del usuario (una contraseña, un certificado digital, un token CSRF, etc.)
  • LoginSuccessEvent, se lanza cuando las credenciales son válidas.
  • LoginFailureEvent, se lanza cuando las credenciales son erróneas.

¡Eso es todo! Estos tres eventos sencillos te dan toda la flexibilidad que necesitas en tus aplicaciones.

3) Guards renovados

Los guards de seguridad se introdujeron en Symfony 2.8 mediante la interfaz GuardAuthenticatorInterface. El nuevo sistema simplifica muchas de sus funcionalidades y mejora otras. Para empezar, el método checkCredentials() se ha eliminado porque ya no hace falta y los métodos getCredentials() y getUser() se han fusionado en un nuevo método llamado authenticate().

Esto a su vez introduce un par de conceptos nuevos:

  • Passport, el método authenticate() devuelve un "pasaporte de seguridad" que contiene el objeto del usuario y las credenciales necesarias para autenticarlo.
  • Badges, la información adicional que necesita el pasaporte.

Los listeners que escuchan el evento CheckPassportEvent validan tanto el pasaporte como los badges. Si todos los badges se resuelven correctamente, entonces el usuario se autentica.

El siguiente ejemplo simplificado muestra el nuevo sistema en la práctica en un formulario de login (tu no tienes que hacer nada de esto porque Symfony ya incluye autenticadores para todos los casos habituales, como los formularios de login):

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
 
class FormAuthenticator implements AuthenticatorInterface
{
    // ...
 
    public function authenticate(Request $request): PassportInterface
    {
        // buscar al usuario en base a su email indicado en el formulario
        $user = $this->userRepository->findOneByEmail($request->get('email'));
        if (!$user) {
            throw new UsernameNotFoundException();
        }
 
        return new Passport($user, new PasswordCredentials($request->get('password')), [
            // añadir protección CSRF mediante un campo llamado "csrf_token"
            new CsrfTokenBadge('loginform', $request->get('csrf_token')),
 
            // y añadir también soporte para actualizar el hash de la contraseña
            new PasswordUpgradeBadge($request->get('password'), $this->userRepository)
        ]);
    }
}

El nuevo sistema de seguridad está desactivado por defecto, pero puedes activarlo mediante esta opción:

# config/packages/security.yaml
security:
    # ...
    enable_authenticator_manager: true

Muy pronto actualizaremos todos los artículos sobre seguridad de la documentación de Symfony para usar este nuevo sistema. Mientras, puedes leer el siguiente artículo: Meet the new Symfony Security: Authenticators publicado por Wouter De Jong, el principal programador detrás del nuevo sistema de seguridad. Además, este artículo se basa completamente en el artículo de Wouter.

Esta funcionalidad fue contribuida por Wouter De Jong en el pull request #33558.


Fuente: New in Symfony 5.1: Updated Security System

Comentarios

Publicada el

26 de mayo de 2020

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.