Afficher les liens selon les autorisations de l’access control

Ce contenu a 1 an et n'est donc peut-être plus à jour.

Si vous souhaitez restreindre l’accès à certaines parties de votre application Symfony, vous avez plusieurs solutions.
La plus simple d’entre elles est l’utilisation des access control dans le fichier security.yml: il suffit de mettre le début de l’URL à contrôler, les rôles qui y ont accès et terminé, ça fonctionne.

Résultat, si un utilisateur n’a pas l’accès à une page mais qu’il clique à un lien y menant, il se retrouvera face à une page d’erreur qui lui explique qu’il n’a pas l’autorisation de se trouver là.

Maintenant, le mieux c’est aussi de ne pas afficher les liens dans votre template Twig si l’utilisateur n’y a pas accès !
Pour ce faire, il suffit d’utiliser la fonction is_granted:

Cela fonctionne avec n’importe quel rôle.

C’est très simple et rapide à mettre en place. Oui mais voilà, si vous changez d’avis et que vous souhaitez changer le rôle qui a accès à une page (voire en rajouter un), il faudra faire la modification dans le fichier security.yml ET dans le template twig. Pas grave si vous avez une toute petite application, plus problématique quand il commence à y avoir pas mal de lien à contrôler…

Ce que je vous propose aujourd’hui, c’est de n’avoir à faire des modifications que dans le fichier security.yml sans devoir toucher le template à chaque fois.
Ça vous dit ? Alors suivez moi ! 🙂

Nous allons tout d’abord commencer par créer un service qu’on va appeler AccessControlService et qui sera placé dans le répertoire src/VotreBundle/Service :

Ensuite, pour que celui-ci fonctionne, nous allons l’enregistrer dans la liste des services ( src/VotreBundle/Resources/config/services.yml ):

Alors, qu’est-ce que fait ce service ?
Il va tout simplement vérifier que pour un chemin donné (via son path), un utilisateur a le droit d’y accéder. Pour cela, il récupère les différents access_control ainsi que les rôles qui ont des droits d’accès dessus grâce à l’accessMap, ensuite il va tout bêtement parcourir les différents rôles qui ont le droit d’accéder à ce path et comparer avec les rôles de l’utilisateur.

Ça, c’est fait. Maintenant comment dire à Symfony que je veux utiliser ce service à chaque fois que j’appelle la fonction is_granted dans mon template ?
Et bien en utilisant un Voter ! En gros, c’est une classe qui dit si oui ou non elle accepte de donner l’accès à une page.
Ce qu’on va faire, c’est créer un Voter qui utilise notre service précédemment créé:

Et, tout comme pour l’AccessControlService pour que celui-ci fonctionne, nous allons l’enregistrer dans la liste des services, à la suite de l’autre ( src/VotreBundle/Resources/config/services.yml ):

Je n’explique pas tout dans le détail, les commentaires devraient vous aider à comprendre 🙂

Attention, je ne l’ai pas précisé mais il est indispensable que votre entité User ait la méthode getRoles() ! Sinon cela ne fonctionnera pas !
Maintenant, si la magie a opérée, dans votre template Twig il vous suffira de mettre:

Plus besoin de spécifier de rôle, c’est automatiquement calibré sur l’utilisateur en cours ! Il vous suffit juste de passer le path en paramètres et l’AccessControlService se chargera de vérifier si la route correspond à l’un des rôles de l’utilisateur (oui ça fonctionne aussi si l’utilisateur à plusieurs rôles).

Maintenant, si vous souhaitez changer le rôle qui a accès à ce path, il vous suffit de le modifier dans le security.yml, déconnecter votre utilisateur, le reconnecter et hop, les liens s’affichent/se cachent automatiquement ! C’est magique 🙂

0 0 vote
Article Rating
S'abonner
Me notifier des
guest
2 Commentaires
plus anciens
plus récents plus de votes
Inline Feedbacks
View all comments
JP_

Salut, super article. Je pensais être le seul a avoir besoin de ça.
En revanche, vous avez copié collé deux fois le fichier AccessControlService.
Il manque le Fichier AccessControlVoter.

Cependant je pense pouvoir compléter de mon coté, donc un grand merci.