Séance 12 : Sécurité et voters

Objectif du cours

  • quand utiliser un Voter plutôt qu’un ROLE_* en dur

  • comment créer un voter

  • comment l’utiliser :

    • dans un contrôleur (denyAccessUnlessGranted)

    • dans Twig (is_granted)

  • comment débugger rapidement (le “pourquoi c’est refusé ?”)


Rappel : pourquoi un Voter ?

Les rôles (ROLE_ADMIN, ROLE_USER) répondent à : “qui es-tu ?” Un voter répond à : “as-tu le droit de faire X sur CET objet précis ?”

Exemples :

  • “un message est éditable seulement par son auteur”

  • “un modérateur peut supprimer n’importe quel message”

  • “un message verrouillé ne peut plus être modifié (même par l’auteur)”

👉 Donc dès qu’il y a un objet (Message, Post, Document…) + une règle métier, Voter.


Modèle d’exemple : Message de forum

On imagine une entité Message :

  • content

  • author (User)

  • createdAt

  • locked (bool) : message verrouillé par un modo

Règles métiers (exemple simple) :

  • VIEW : tout le monde connecté peut voir

  • EDIT :

    • auteur peut éditer si pas locked

    • modérateur / admin peut éditer même si locked

  • DELETE :

    • auteur peut supprimer dans les 15 minutes après création et si pas locked

    • modérateur / admin peut supprimer à tout moment


Étape 1 — Créer le Voter

Créer src/Security/Voter/MessageVoter.php

Points importants

  • supports() : “est-ce que je suis concerné ?”

  • voteOnAttribute() : “j’applique mes règles”

  • Security $security permet de réutiliser isGranted() pour un rôle “global”.


Étape 2 — Utiliser le voter dans un contrôleur

Exemple d’édition :

Exemple suppression :


Étape 3 — Utiliser dans Twig

Afficher les boutons selon les droits :


Étape 4 — Bonnes pratiques

  • Constantes pour les attributs (MESSAGE_EDIT) : évite les fautes de frappe.

  • Ne pas mettre “trop” de règles dans le contrôleur : le contrôleur appelle denyAccessUnlessGranted.

  • Le voter doit rester lisible : extraire des méthodes (canEdit, canDelete).

  • Si les règles deviennent grosses : créer un petit service métier MessagePermissionChecker et l’utiliser dans le voter.


Débogage rapide

Si “ça marche pas” :

  1. Vérifier que supports() renvoie bien true (bon attribut + bon objet)

  2. Vérifier que le $subject est bien une entité Message (pas null, pas un id)

  3. Vérifier que l’utilisateur est bien connecté ($user instanceof User)

Commande utile :


Mis à jour

Ce contenu vous a-t-il été utile ?