L3 Info : PHP et Applications Web
 
◃  Ch. 11 Some old Stuff (chapitre non maintenu)  ▹
 

Authentification

  • Symfony intègre également des outils permettant d'identifier les utlisateurs et ainsi de contrôler l'accès des routes.
  • Dans app/config/security.yml on peut paramétrer le contrôle d'accès :
    • # app/config/security.yml
      security:
          providers:
              in_memory:
                  memory: ~
      
          firewalls:
              dev:
                  pattern: ^/(_(profiler|wdt)|css|images|js)/
                  security: false
      
              main:
                   anonymous : ~
    • le firewal dev concerne l'accès aux outils de développement la route /_profiler par exemple ;
    • Les autres urls sont gérées par le firewal main, ici tout est accessible en mode anonyme c'est à dire sans authentification.
  • Un premier mode d'authentification : à l'ancienne via une popup
    • On rajoute ce mode d'authentification dans le fichier security.yml :
      security:
          # ...
          firewalls:
              # ...
              main:
                  anonymous : ~
                  http_basic: ~
    • On construit une nouvelle route d'administration :
      // src/AppBundle/Controller/DefaultController.php
      // ...
      
      use Symfony\Bundle\FrameworkBundle\Controller\Controller;
      use Symfony\Component\HttpFoundation\Response;
      use Symfony\Component\Routing\Annotation\Route;
      
      class DefaultController extends Controller
      {
          /**
           * @Route("/admin")
           */
          public function adminAction()
          {
              return new Response('Admin page!');
          }
      }
    • on complète security.yml :
      # app/config/security.yml
      security:
          # ...
          firewalls:
              # ...
              main:
                  # ...
      
          access_control:
              # require ROLE_ADMIN for /admin*
              - { path: ^/admin, roles: ROLE_ADMIN }
    • On configure les utilisateurs :
      # app/config/security.yml
      security:
          providers:
              in_memory:
                  memory:
                      users:
                          lambda:
                              password: lambdapass
                              roles: 'ROLE_USER'
                          admin:
                              password: teapot
                              roles: 'ROLE_ADMIN'
          # ...
    • Ce n'est pas suffisant ! il faut encore préciser l'encodage des mots de passe :
      # app/config/security.yml
      security:
          # ...
      
          encoders:
              Symfony\Component\Security\Core\User\User: plaintext
          # ...
    • Cryptage du mot de passe :
      # app/config/security.yml
      security:
          # ...
      
          encoders:
              Symfony\Component\Security\Core\User\User:
                  algorithm: bcrypt
                  cost: 12
    • On encode les mots de passe avec la console :
      $ php bin/console security:encode-password
      
      Symfony Password Encoder Utility
      ================================
      
       Type in your password to be encoded:
       >
      
       ------------------ ---------------------------------------------------------------
        Key                Value
       ------------------ ---------------------------------------------------------------
        Encoder used       Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder
        Encoded password   $2y$12$68BvHejD/f4RKrSnXP7xsuTYGXGmQfcD.O/xwG7q64hXbXmgluPd2
       ------------------ ---------------------------------------------------------------
      
       ! [NOTE] Self-salting encoder used: the encoder generated its own built-in salt.
      
      
       [OK] Password encoding succeeded
      
    • On met à jour le fichier security.yml :
          # https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
          providers:
              in_memory:
                  memory:
                      users:
                          lambda:
                              password: $2y$12$68BvHejD/f4RKrSnXP7xsuTYGXGmQfcD.O/xwG7q64hXbXmgluPd2
                              roles: 'ROLE_USER'
                          admin:
                              password: $2y$12$RGQrY.D3VoeRVxDuL9lHE.Bf3Hj2z8RSFDNMinEk6xfT7SjPTeFJe
                              roles: 'ROLE_ADMIN'
              #...
    • C'est prêt !
  • Quelques inconvénients demeurent : on ne peut pas se déconnecter, les popups c'est môche, on a déjà d'autres systèmes qui gère des utilisateurs, ...
  • Besoin #1 : hiérarchiser les rôles
    # app/config/security.yml
    security:
        # ...
    
        role_hierarchy:
                ROLE_ADMIN:       ROLE_USER
    Attention tous les noms de rôle doivent commencer par ROLE_
  • Besoin #2 : Gestion du contrôle d'accès
    # app/config/security.yml
    security:
        # ...
        access_control:
            # require ROLE_ADMIN for /admin*
            - { path: ^/admin, roles: ROLE_ADMIN }
            - { path: ^/lambda, roles: ROLE_USER }
            - { path: ^/lmsf, roles: ROLE_USER }
    Attention filtre les routes dans l'ordre de déclaration et adopte la première politique rencontrée
  • Besoin #3 : gestion du contrôle d'accès au sein du controleur
    public function helloAction($name)
    {
        // The second parameter is used to specify on what object the role is tested.
        $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');
        //...
    }
    ou bien à l'aide d'annotation
    // ...
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
    
    /**
     * @Security("has_role('ROLE_ADMIN')")
     */
    public function helloAction($name)
    {
        // ...
    }
    Génère une Réponse HTTP 403 si l'authentification n'est pas validée
  • Besoin #4 : dans les template
    {% if is_granted('ROLE_ADMIN') %}
        <a href="...">Delete</a>
    {% endif %}
    La fonction interne is_granted() fait le job !
  • Besoin #5 : Créer un formulaire de login : Doc symfony