Passage de 5.2 à 5.3

Présentation

Je n’avais pas touché à un projet depuis longtemps (Sf 5.1). J’ai repris car je voulais ajouter quelque chose et j’ai commencé (erreur) par vouloir mettre à jour Symfony.

Le passage de 5.1 en 5.2 n’a pas posé de souci particulier : renommage des imports doctrine.

Le passage de 5.2 en 5.3 n’a pas posé de soucis mais a généré une très très grande liste d’éléments à changer …

Remaining direct deprecation notice

Ajout getUserIdentifier

1x: Class "App\Entity\User" should implement method "Symfony\Component\Security\Core\User\UserInterface::getUserIdentifier()": returns the identifier for this user (e.g. its username or e-mailaddress)
1x in APIBiereCommentaireControllerTest::testGetCommentaires from App\Tests\Controller\API

Ici la mise à jour est simple : il suffit d’ajouter la méthode getUserIdentifier à la classe User. Dans mon cas, elle retourne l’ancien résulat de getUserName.

Modification de l’identification par login

Il semble que la partie sécurité est pas mal bougé ….

1x: The "App\Security\LoginFormAuthenticator" class extends "Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator" that is deprecated since Symfony 5.3, use the new authenticator system instead.
1x in APIBiereCommentaireControllerTest::testGetCommentaires from App\Tests\Controller\API

Plusieurs actions à réalisée basé sur la nouvelle version de la documentation Symfony et quelqu’un qui a gentillement tout expliqué ici :

Quelques modifications dans le fichier security.yaml comme l’activation du nouveau système : enable_authenticator_manager: true. Ensuite, il faudrait aller modifier le code de LoginFormAuthenticator qui est dans mon projet mais un composant de base est fourni par Symfony. Pour l’activer :

#guard:
#    authenticators:
#        - App\Security\LoginFormAuthenticator
form_login:
    login_path: app_login
    check_path: app_login
    enable_csrf: true

Remaining indirect deprecation notices

Ajout d’une interface et méthode sur User

9x: Since symfony/security-http 5.3: Not implementing the "Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface" interface in class "App\Entity\User" while using password-based authentication is deprecated.

Simple, il faut ajouter l’interface attendue.

Mise à jour des mots de passe

9x: Since symfony/doctrine-bridge 5.3: The "Symfony\Component\Security\Core\User\PasswordUpgraderInterface::upgradePassword()" method expects an instance of "Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface" as first argument, the "App\Entity\User" class should implement it.

Implémenter une nouvelle interface et une méthode qui permet à Symfony de mettre à jour les hash des utilisateurs si l’algo change :

/**
 * Used to upgrade (rehash) the user's password automatically over time.
 */
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
{
    if (!$user instanceof User) {
        throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', \get_class($user)));
    }

    $user->setPassword($newEncodedPassword);
    $this->_em->persist($user);
    $this->_em->flush();
}

LexikJWTAuthentificationBundle

Cf la doc du bundle dans la partie 5.3 higher.

1x: Since symfony/security-guard 5.3: The "Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken" class is deprecated, use the new authenticator system instead.
    1x in APIBiereCommentaireControllerTest::testPostCommentaires from App\Tests\Controller\API
1x: Since symfony/security-guard 5.3: The "Symfony\Component\Security\Guard\Token\GuardTokenInterface" class is deprecated, use the new authenticator system instead.
    1x in APIBiereCommentaireControllerTest::testPostCommentaires from App\Tests\Controller\API
1x: The "Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserTokenInterface" interface extends "Symfony\Component\Security\Guard\Token\GuardTokenInterface" that is deprecated since Symfony 5.3, use the new authenticator system instead.
    1x in APIBiereCommentaireControllerTest::testPostCommentaires from App\Tests\Controller\API
1x: The "Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticationJWTUserToken" class extends "Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken" that is deprecated since Symfony 5.3, use the new authenticator system instead.
    1x in APIBiereCommentaireControllerTest::testPostCommentaires from App\Tests\Controller\API
1x: The "Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\JWTUserToken" class implements "Symfony\Component\Security\Guard\Token\GuardTokenInterface" that is deprecated since Symfony 5.3, use the new authenticator system instead.
    1x in APIBiereCommentaireControllerTest::testPostCommentaires from App\Tests\Controller\API
1x: The "Lexik\Bundle\JWTAuthenticationBundle\Security\Guard\JWTTokenAuthenticator" class implements "Symfony\Component\Security\Guard\AuthenticatorInterface" that is deprecated since Symfony 5.3, use the new authenticator system instead.
    1x in APIBiereCommentaireControllerTest::testPostCommentaires from App\Tests\Controller\API

Mise à jour du fichier security.yaml:

#guard:
#    authenticators:
#        - lexik_jwt_authentication.jwt_token_authenticator
# Ajout de la ligne
jwt: ~

Other deprecation notices

session.storage.factory.service

106x: Since symfony/framework-bundle 5.3: The "session.storage.factory.service" service is deprecated, use "session.storage.factory.native", "session.storage.factory.php_bridge" or "session.storage.factory.mock_file" instead.

Il faut corriger le fichier framework.yaml en test :

framework:
    test: true
    session:
        # storage_id: session.storage.mock_file
        storage_factory_id: session.storage.factory.mock_file

Quelques corrections

  • Utilisation de loginUser,
  • Utilisation de static::getContainer()

security.password_encoder

3x: Since symfony/security-bundle 5.3: The "security.password_encoder" service is deprecated, use "security.user_password_hasher" instead.
   3x in NavigationTest::testNavigation from App\Tests\Controller\Admin
3x: Since symfony/security-bundle 5.3: The "security.encoder_factory.generic" service is deprecated, use "security.password_hasher_factory" instead.
    3x in NavigationTest::testNavigation from App\Tests\Controller\Admin
1x: Since symfony/security-core 5.3: The "Symfony\Component\Security\Core\Encoder\UserPasswordEncoder" class is deprecated, use "Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher" instead.
    1x in NavigationTest::testNavigation from App\Tests\Controller\Admin
1x: Since symfony/security-core 5.3: The "Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface" interface is deprecated, use "Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface" instead.
    1x in NavigationTest::testNavigation from App\Tests\Controller\Admin
1x: Since symfony/security-core 5.3: The "Symfony\Component\Security\Core\Encoder\EncoderFactory" class is deprecated, use "Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory" instead.
    1x in NavigationTest::testNavigation from App\Tests\Controller\Admin
1x: Since symfony/security-core 5.3: The "Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface" class is deprecated, use "Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface" instead.
    1x in NavigationTest::testNavigation from App\Tests\Controller\Admin

Il faut suivre ce qui est écrit ici. Il faut donc modifier le fichier security.yaml ainsi que les endroits où les mots de passe sont encodés.

Un point cependant, il ne suffit pas de demander l’injection de UserPasswordHasherInterface: il faut en faire demander l’injection de PasswordHasherFactoryInterface qui va retourner via getPasswordHasher, l’instance qui va permettre le hash

$password = $this->passwordHasherFactoryInterface->getPasswordHasher($obj)->hash($obj->getPassword());