Question

Je travaille sur une application Web Rails actuellement utilisée par une vingtaine d'utilisateurs.

Certaines parties de l'application ne sont accessibles que par certains utilisateurs. Nous avons donc déjà mis en place un cadre d'autorisation de base, que j'ai mis en place à l'aide du plugin acts_as_authenticated.

Les privilèges des utilisateurs dépendent du service dans lequel ils travaillent. Ainsi, par exemple, l'administration a accès à toutes les parties de l'application, alors que la comptabilité n'a accès qu'aux pièces liées à la comptabilité et que les ventes n'ont accès qu'aux pièces liées aux ventes. , etc.

D'autre part, les utilisateurs voient les liens vers les actions pour lesquelles ils ne disposent pas de privilèges suffisants. Par exemple, ceux du service des ventes voient un lien vers les enregistrements financiers dans le menu principal, mais quand ils cliquent dessus, rien ne se passe. En effet, il n’existe pas de méthode efficace pour interroger les privilèges de l’utilisateur à

Je souhaite changer cela de deux manières:

  1. Je souhaite introduire une autorisation plus fine. Actuellement, l'autorisation est faite au niveau du contrôleur. Je veux faire cela au niveau de l'action ou du modèle. Par exemple, je souhaite que les responsables des ventes puissent créer et mettre à jour des paiements, sans les supprimer.

  2. Je souhaite pouvoir interroger efficacement les privilèges utilisateur afin de pouvoir supprimer les liens inutiles (et déroutants) de l'interface.

Selon vous, quel est le moyen le plus élégant de mettre en œuvre cela?

Les réponses spécifiques à Rails ne sont pas nécessaires, je veux simplement savoir comment cela devrait être implémenté dans une application pilotée par les données.

Enfin, voici comment il est mis en œuvre actuellement:

def authorized?
  current_user.role.foo? or current_user.role.bar?
end

Et voici mon idée de départ, qui, à mon avis, n’est pas la meilleure façon de résoudre ce problème:

+------------+------------+---------+
| department | controller | action  |
+------------+------------+---------+
| accounting | payments   | index   |
| accounting | payments   | new     |
| accounting | payments   | create  |
| accounting | payments   | edit    |
| accounting | payments   | update  |
| accounting | payments   | destroy |
| sales      | payments   | new     |
| sales      | payments   | create  |
| sales      | payments   | edit    |
| sales      | payments   | update  |
+------------+------------+---------+

ou

+------------+----------+-------+--------+------+--------+--------+
| department | model    | list  | create | read | update | delete |
+------------+----------+-------+--------+------+--------+--------+
| accounting | payments | TRUE  | TRUE   | TRUE | TRUE   | TRUE   |
| sales      | payments | FALSE | TRUE   | TRUE | TRUE   | FALSE  |
+------------+----------+-------+--------+------+--------+--------+
Était-ce utile?

La solution

Le concept de base de l'autorisation, tel que je le comprends, est un rôle. Le rôle peut exprimer différentes choses:

  1. relation d’un utilisateur avec le système dans son ensemble (par exemple, être un administrateur du système)
  2. relation d’un utilisateur avec un certain type d’entités (par exemple, modérateur de commentaires)
  3. relation d’un utilisateur avec une entité particulière (par exemple, propriétaire d’une ressource)
  4. une autre relation complexe (par exemple, être l'ami d'un utilisateur propriétaire d'une ressource)
  5. cet utilisateur possède un ou plusieurs attributs ou répond à un message d'une manière particulière (par exemple, être adolescent)

Un système d'autorisation très détaillé devrait vous permettre de définir le rôle d'un utilisateur en fonction de l'un des critères mentionnés ci-dessus. En outre, cela devrait vous permettre de définir plusieurs rôles pour un utilisateur. (Les formes les plus simples de plug-ins d'autorisation pour Rails vous permettent généralement de définir uniquement le premier type de rôles et de définir un seul rôle pour un utilisateur.)

L'autre partie de l'autorisation est un mécanisme qui détermine la partie du code à exécuter (ou à ne pas exécuter) en fonction du fait qu'un utilisateur remplit ou non un rôle (un ensemble de rôles). Pour appliquer ce mécanisme, nous devons trouver les points sur lesquels l’autorisation doit avoir lieu et sélectionner les rôles pour lesquels le code doit ou ne doit pas être exécuté.

Pour Rails, la solution consiste à définir des rôles au niveau du modèle et à laisser un mécanisme d'autorisation (définition des rôles autorisés pour les parties de code que je souhaite autoriser et demande si l'utilisateur actuel dispose du rôle autorisé à exécuter la partie) entièrement pour les contrôleurs / vues.

Pour cela, j'utilise un plug-in rail-autorisation-plug-in optimisé qui offre toutes les possibilités que je viens de mentionner (divers types de rôles, plusieurs rôles pour un utilisateur, l'autorisation sur le contrôleur et le niveau de vue).

Autres conseils

vous devrez peut-être introduire la notion de "points de fonction" ou de "fonctionnalités" dans votre modèle en tant que points de contrôle pour l'accès; une "fonctionnalité" peut avoir une "fonctionnalité parent" facultative pour former une hiérarchie. Vous décidez ce qui est ou non une fonctionnalité et vérifiez les autorisations par programme. Cela devrait également vous permettre de vérifier l'accès au niveau des fonctionnalités avant de dessiner un menu, afin que les utilisateurs ne voient jamais les liens vers des pages auxquelles ils ne sont pas autorisés.

Une situation / solution similaire est décrite ici

Parmi vos deux propositions, la première option est un peu meilleure car elle vous permet d’ajouter des actions qui ne sont peut-être pas au niveau du modèle. J'imagine que vous rencontrerez un cas où le second modèle ne suffirait pas et qu'il vous faudra soit modifier le schéma, soit commencer à répartir la logique des autorisations dans votre application (par exemple, "Utilisateurs sans" créer "). l'accès ne peut pas non plus exécuter la méthode xxx ")

Je pense que la raison pour laquelle la solution n'a pas l'air très sèche est qu'il y a répétition:

  1. dans les noms de département et
  2. Dans les capacités du département

En ce qui concerne le n ° 1, il serait judicieux de créer une table des départements et de donner un identifiant à chaque département.

En ce qui concerne le point 2, je suis d’accord avec le premier commentaire. Vous pouvez probablement regrouper les différents contrôleurs et actions en groupes fonctionnels, puis définir une relation plusieurs à plusieurs (table de mappage) entre utilisateurs et fonctions. Les fonctions auraient alors une relation un-à-plusieurs avec les actions / contrôleurs qu'elles autorisent. Cela vous permettrait, avec un minimum de répétitions, de dire des choses telles que "la comptabilité et les ventes devraient pouvoir lire tous les tableaux financiers".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top