Aller au contenu
M08 · C. Protéger les applications Web

Gérer les rôles des utilisateurs

Le contrôle d'accès par rôle (RBAC) - rôles, permissions, matrice des droits -, sa mise en œuvre en PHP avec une fonction de contrôle unique appelée en haut de chaque page, le stockage des rôles en base, la séparation des tâches et les erreurs classiques (contrôle oublié, élévation de privilège, rôle modifiable par l'utilisateur).

1Situer

L'équipe de Souk Atlas grandit : des préparateurs consultent les commandes, une gérante modifie les prix, les clients voient leur compte. Plutôt que d'écrire des conditions partout (« si c'est Leila ou Hamza... »), on regroupe les droits en rôles. C'est la façon standard de gérer les autorisations d'une application.

2Comprendre

Utilisateurs, rôles, permissions
utilisateursrôlespermissions Amina Hamza Leila client préparateur admin ses commandes toutes, statut modifier_prix autoriser('modifier_prix')

On ne donne pas les droits à chaque personne : on donne un rôle, et le rôle porte les permissions.

1 / 4

Rôles et permissions

On vérifie une permission, pas un rôle : autoriser('modifier_prix') plutôt que if ($role === 'admin'). Le jour où l’on crée un rôle « responsable catalogue » qui peut aussi modifier les prix, il suffit de mettre à jour la matrice, sans toucher aux pages.

Une seule fonction de contrôle

function autoriser(string $permission): void
{
    $u = $_SESSION['utilisateur'] ?? null;
    if (!$u) {
        header('Location: connexion.php');
        exit;
    }
    if (!in_array($permission, PERMISSIONS[$u['role']] ?? [], true)) {
        http_response_code(403);
        exit('Accès refusé');
    }
}

Chaque page protégée commence par une ligne : autoriser('voir_commandes');. Le contrôle est au même endroit partout, facile à relire et à tester.

Les erreurs classiques

  • Le contrôle seulement dans l’interface : le menu cache le lien, mais la page ne vérifie rien (leçon B.3).
  • Le rôle modifiable par l’utilisateur : dans un cookie, un champ caché, ou par assignation de masse (exercice 2).
  • L’élévation de privilège : un préparateur qui peut s’attribuer le rôle admin parce que la page de gestion des comptes vérifie seulement qu’il est connecté.
  • Les droits qui s’accumulent : un employé qui change de poste garde ses anciens rôles. On revoit les rôles régulièrement et on retire les accès au départ.
Exemple simple

Les badges de l'hôpital

À l'hôpital, la couleur du badge (médecin, infirmier, visiteur) ouvre ou non les portes. On ne programme pas chaque porte pour chaque personne : on donne un rôle à la personne, et des droits au rôle.

Exemple simple

Le caissier et le contrôleur

Celui qui encaisse n'est pas celui qui vérifie la caisse le soir. Séparer ces rôles évite qu'une seule personne puisse commettre et cacher une erreur, ou une fraude.

3Manipuler

Les pages appellent autoriser() mais la fonction ne vérifie rien. Écrivez-la à partir de la matrice PERMISSIONS. Comptes : amina.benali@mail.ma / Atlas2025 (client), hamza@soukatlas.ma / Souk2025 (préparateur), leila@soukatlas.ma / Tajine#Fes2025 (admin).
Pas à pas dans le lab ↗ Cliquez sur Exécuter : PHP 8.3 démarre dans votre navigateur (environ 5 Mo à télécharger, une seule fois).

La page s'affichera ici.

Le navigateur demandera /connexion.php au serveur, qui exécutera le PHP et renverra du HTML.

Entre le navigateur et le serveur aucun échange pour l'instant

Consignes 0 / 5

  1. Sans connexion, commandes.php renvoie vers connexion.php
  2. Le préparateur voit les commandes
  3. La cliente reçoit 403 sur la page des commandes
  4. Le préparateur ne peut pas changer un prix (403, prix inchangé)
  5. L'administratrice change le prix du tajine à 200 DH

4Pratiquer

Exercice 1 · Les rôles dans la base

Concevez les tables pour stocker utilisateurs, rôles et permissions dans MySQL (un utilisateur peut avoir plusieurs rôles), puis la requête qui dit si l'utilisateur 3 a la permission 'modifier_prix'.

Voir le corrigé
CREATE TABLE roles (id INT AUTO_INCREMENT PRIMARY KEY, nom VARCHAR(30) NOT NULL UNIQUE);
CREATE TABLE permissions (id INT AUTO_INCREMENT PRIMARY KEY, code VARCHAR(50) NOT NULL UNIQUE);
CREATE TABLE role_permission (
  role_id INT NOT NULL, permission_id INT NOT NULL,
  PRIMARY KEY (role_id, permission_id),
  FOREIGN KEY (role_id) REFERENCES roles(id), FOREIGN KEY (permission_id) REFERENCES permissions(id)
);
CREATE TABLE utilisateur_role (
  utilisateur_id INT NOT NULL, role_id INT NOT NULL,
  PRIMARY KEY (utilisateur_id, role_id),
  FOREIGN KEY (role_id) REFERENCES roles(id)
);

SELECT COUNT(*) > 0 AS autorise
FROM utilisateur_role ur
JOIN role_permission rp ON rp.role_id = ur.role_id
JOIN permissions p ON p.id = rp.permission_id
WHERE ur.utilisateur_id = 3 AND p.code = 'modifier_prix';

Exercice 2 · L'élévation de privilège

Le formulaire « Modifier mon profil » envoie prenom, email et telephone. Le script fait UPDATE utilisateurs SET ... avec toutes les clés de $_POST. Quel est le risque, et comment l'éviter ?

Voir le corrigé
Un utilisateur ajoute un champ role=admin à la requête (outils de développement) : le script met aussi à jour la colonne role, et le client devient administrateur. C'est l'« assignation de masse ».
Parade : n'accepter qu'une liste blanche de champs modifiables (prenom, email, telephone), et ne changer le rôle que depuis une page réservée aux administrateurs, avec la permission gerer_comptes.

5Vérifier

1. Dans le modèle RBAC, à quoi sont attachées les permissions ?
2. Quel code HTTP renvoyer à un utilisateur connecté qui n'a pas le droit d'accéder à une page ?
3. Où le rôle de l'utilisateur doit-il être lu pour décider d'un accès ?