8 - Sécurité: limiter les actions de l'utilisateur
Etre connecté ne suffit pas forcément pour la sécurité, un utilisateur authentifié ne doit pas forcément accéder à des ressources ou actions qui ne lui sont pas destinées.
Nous allons donc voir 3 façons de mettre en place une sécurité, de la plus simple et globale à la plus complexe mais fine.
1 - Les access control
Symfony propose un méchanisme très simple et haut niveaux pour les règles de sécurité les plus primaire: la définition des access control dans le security.yaml
La doc officielle:
C'est la façon la plus simple de faire, il suffit de renseigner les urls (ou un pattern) qui sera associé à un role minimum:
Ici, on indique que toutes les url commencant par /admin nécessite au minimu le role ROLE_ADMIN
Attention cependant, comme préciser dans le fichier, seul le premier match sera utilisé.
2 - Les règles simple directement sur des opérations
Prenons l'exemple de mes opérations d'écriture sur ma ressource Category (POST, PUT, DELETE). Selon ma règle métier, seul un admin devrait être en capacité de faire cela.
Cette règle étant assez fine, on ne va pas la mettre dans le security.yaml mais directement dans ma resource Category.
Actuellement, elle ressemble à:
On va pouvoir venir facilement ajouter des paramètres de sécurité sur les attributs voulus:
Ici, j'ai simplement eu besoin de rajouter la fonction "is_granted" fournis par Symfony qui permet de checker si oui ou non l'utilisateur courant possède à minima le role admin.
3 - les voters
Parfois pour des cas les plus compliqués, les annotations ne suffisent et vous devez écrire du code, c'est à ce moment qu'il vous faudra un voter.
Comme d'habitude, si vous êtes familier du Maker de Symfony, il vous suffit d'une commande pour créer le squelette de votre voter:
bin/console make:voter
Une fois épuré, notre squelette ressemble à:
On a globalement accès à deux méthode dans ce voter:
supports: Qui nous permet de vérifier si notre Voter peut "voter" la requête actuel. (si return true alors peut voter, false ne peut pas)voteOnAttribute: Qui effectue le "vote". (si return true alors l'action est authorisée, si false alors elle ne l'est pas)
Le fonctionnement reste donc tout de même assez simpliste.
Pour l'usage d'un voter, on utilisera la même méthode que sur 2 - Les règles simple directement sur des opérations, à savoir:
On aperçoit ici plusieurs choses:
Nous passons désormais un "attribute" et un "subjet" à notre fonction "is_granted", qui elle même les passera aux fonctions de notre Voter
Sur le
Postnous sommes passé de "security" à "securityPostDenormalize", pour préciser à ApiPlatform qu'il ne doit pas appliquer la sécurité directement mais qu'il doit d'abord transformé la requête de création en un objet
Maintenant, on va pouvoir voter:
Dans notre cas, on fait un voter très basique: on vérifié que le sujet (notre catégorie) à bien été créée par l'utilisateur courant.
Sinon on ne donne pas les droits.
C'était un cas très simple et optimiste, mais on pourrait très bien avoir 3 "attributes" différents dans ce voter (un pour POST, un pour PUT et un pour DELETE) avec chacun leur propre logique pour autoriser ou non.
On pourrait même avoir plusieurs Voter pour une seule et même resources.
Bref les possibilités sont infinies.
Last updated