web-dev-qa-db-fra.com

Meilleures pratiques pour la conception de rôles d'utilisateur et de système d'autorisation?

J'ai besoin d'ajouter des rôles d'utilisateur et un système d'autorisation dans mon application Web construite en utilisant PHP/MySQL. Je veux avoir cette fonctionnalité:

  1. Un utilisateur racine peut créer des sous-racines, des groupes, des règles et des utilisateurs normaux (tous les privilèges).
  2. Les sous-racines ne peuvent créer que des règles, des autorisations et des utilisateurs pour son propre groupe (pas de groupe).
  3. Un utilisateur peut accéder au contenu créé par lui ou son groupe, en fonction de l'autorisation qui lui est attribuée, par racine de groupe.

J'ai besoin que le système soit suffisamment flexible pour que de nouveaux rôles et autorisations soient attribués au contenu.

J'ai une table users stockant la clé de groupe avec d'autres informations. Actuellement, j'utilise deux feilds dans chaque table de contenu, c'est-à-dire createdBy et CreatedByGroup, et j'utilise cela comme le point de savoir si un certain utilisateur a des autorisations. Mais ce n'est pas assez flexible, car pour chaque nouveau contenu, je dois passer par toutes les mises à jour de données et les mises à jour des autorisations. Veuillez m'aider en discutant de vos meilleures pratiques pour la conception de schémas.

40
hash

Le modèle qui convient à vos besoins s'appelle contrôle d'accès basé sur les rôles .

Il existe plusieurs bonnes implémentations en PHP, notamment Zend_Acl (bonne documentation), phpGACL et TinyACL . La plupart des frameworks ont également leurs propres implémentations d'une ACL sous une forme ou une autre.

Même si vous choisissez de lancer la vôtre, cela vous aidera à examiner des solutions bien conçues telles que celles-ci.

34
Eran Galperin

Je pense que les opérateurs au niveau du bit sont le meilleur moyen de mettre en œuvre l'autorisation utilisateur. Ici, je montre comment nous pouvons l'implémenter avec MySQL.

Voici un exemple de tableaux avec quelques exemples de données:

Tableau 1 : Tableau des autorisations pour stocker le nom de l'autorisation avec son bit comme 1, 2, 4, 8 .. etc (multiple de 2)

CREATE TABLE IF NOT EXISTS `permission` (
  `bit` int(11) NOT NULL,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`bit`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Insérez quelques exemples de données dans le tableau.

INSERT INTO `permission` (`bit`, `name`) VALUES
(1, 'User-Add'),
(2, 'User-Edit'),
(4, 'User-Delete'),
(8, 'User-View'),
(16, 'Blog-Add'),
(32, 'Blog-Edit'),
(64, 'Blog-Delete'),
(128, 'Blog-View');

Tableau 2 : Tableau utilisateur pour stocker l'ID utilisateur, le nom et le rôle. Le rôle sera calculé comme la somme des autorisations.
Exemple:

Si l'utilisateur 'Ketan' a l'autorisation de 'User-Add' (bit = 1) et 'Blog-Delete' (bit-64), le rôle sera donc 65 (1 + 64).
Si l'utilisateur "Mehata" a l'autorisation de "Blog-View" (bit = 128) et "User-Delete" (bit-4), le rôle sera donc 132 (128 + 4).

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `role` int(11) NOT NULL,
  `created_date` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

Exemples de données-

INSERT INTO `user` (`id`, `name`, `role`, `created_date`)
   VALUES (NULL, 'Ketan', '65', '2013-01-09 00:00:00'),
   (NULL, 'Mehata', '132', '2013-01-09 00:00:00');

Autorisation de dépôt de l'utilisateur Après la connexion si nous voulons charger l'autorisation d'utilisateur, nous pouvons interroger ci-dessous pour obtenir les autorisations:

SELECT permission.bit,permission.name  
   FROM user LEFT JOIN permission ON user.role & permission.bit
 WHERE user.id = 1

Ici user.role "&" permission.bit est un opérateur Bitwise qui donnera la sortie comme -

User-Add - 1
Blog-Delete - 64

Si nous voulons vérifier la météo, un utilisateur particulier a la permission de modifier ou non

  SELECT * FROM `user` 
     WHERE role & (select bit from permission where name='user-edit')

Sortie = Aucune ligne.

Vous pouvez également voir: http://sforsuresh.in/implemention-of-user-permission-with-php-mysql-bitwise-operators/

35
Suresh Kamrushi

J'avais une structure légèrement différente, mais elle devrait pouvoir servir de référence.

Chaque utilisateur a un "rôle", un "GroupID" associé et une table de groupe pour laquelle le GroupID fait référence. Ensuite, j'ai 3 table d'autorisation.

PermissionMaster(FormName)

PermissionChild(PermissionMasterID, PermissionName, Desc, DefaultValue, DependOn) et

PermissionGroupChild(GroupID, PermissionChildID, Allow)

PermissionMaster contient le nom/formulaire/module auquel l'autorisation se réfère. PermissionChild répertoriera toutes les autorisations possibles disponibles pour chaque maître, telles que "Créer", "Afficher", "Modifier", "Supprimer" et la description (je ne l'avais pas sur la première version et cela a commencé à devenir confus). quand il y a trop de configuration de permission même pour 1 module). J'autorise l'ajout de plus d'enfants pour se référer spécifiquement à une fonction comme "ChangeTimeStamp", ce qui permettrait également une autorisation plus spécifique, puis "Modifier"

PermissionGroupChild est alors le lien entre PermissionChild et la table Group. Chaque groupe aura un ensemble de PermissionChild copié et défini avec le paramètre par défaut. Ensuite, j'ai eu une classe d'autorisation qui effectue la requête de table et vérifie pour chaque utilisateur. Je le charge uniquement lors de la connexion. Ensuite, dans chaque formulaire/module, je vérifie qu'il s'agit de l'autorisation appropriée et applique correctement l'interface utilisateur.

Quant au rôle, je ne l'utilise que sur la page de configuration de la connexion. Une valeur de rôle plus petite signifie un rang supérieur. Ainsi, l'utilisateur ne peut se voir que ceux de la valeur Rôle supérieurs à lui-même. Il/elle peut éditer ceux de rang inférieur à lui-même mais pas similaire.

6
faulty

Vous ne voudrez peut-être pas des groupes d'autorisations. Créez plutôt des groupes d'utilisateurs, accordez des autorisations aux groupes d'utilisateurs et placez les utilisateurs dans des groupes. Les utilisateurs doivent également être en mesure de remplacer les autorisations des groupes dans lesquels ils se trouvent. Le refus doit toujours remplacer l'octroi lorsqu'un utilisateur se trouve dans plusieurs groupes avec l'autorisation.

En résumé:

  • L'utilisateur n'a aucune autorisation ou plus (grany, deny)
  • L'utilisateur est dans zéro ou plusieurs groupes
  • Le groupe a zéro ou plusieurs autorisations (accorder, refuser)
6
Neil Barnwell

J'ai des groupes et des utilisateurs (comme la solution LDAP Active Directory). Donc, si je donne accès au groupe, j'ai besoin que les utilisateurs de ce groupe aient des accès hérités.

Donc, basé sur la réponse @ suresh-kamrushi ci-dessous, j'ai fait ceci:

INSERT INTO `permission` (`bit`, `name`) VALUES
(1,   'add-yes'),
(2,   'add-no'),
(4,   'edit-yes'),
(8,   'edit-no'),
(16,  'del-yes'),
(32,  'del-no'),
(64,  'view-yes'),
(128, 'view-no');

Si l'utilisateur a le bit 00000000, Je prends les deux premiers chiffres 00 cela signifie add-yes et add-no sont hérités des autorisations de groupe.

Si l'utilisateur a le bit 01010110, Je prends les deux premiers chiffres 01 cela signifie add-no s'amorcera sur les autorisations de groupe, donc cet utilisateur n'a aucune autorisation d'ajout. Ce bit indique que l'utilisateur ne peut que voir.

Cela fonctionne également avec les groupes de parents.

Que pensez-vous de cette solution? Quelqu'un a-t-il un meilleur moyen pour cela?

2
Meloman