2008-11-10 7 views
5

Je travaille sur une application Web Rails, et elle est actuellement utilisée par une vingtaine d'utilisateurs.Meilleure façon d'implémenter une autorisation fine pour une application Web?

Certaines parties de l'application ne sont accessibles que par certains utilisateurs, nous avons donc déjà un cadre d'autorisation de base en place, que j'ai implémenté en utilisant le plugin acts_as_authenticated. Les privilèges des utilisateurs dépendent du département dans lequel ils travaillent. Par exemple, l'administration a accès à toutes les parties de l'application, tandis que la comptabilité n'a accès qu'aux parties liées à la comptabilité et que les ventes ont uniquement accès aux données liées aux ventes. parts, etc.

D'autre part, les utilisateurs voient les liens vers des actions pour lesquelles ils ont des privilèges insuffisants. Par exemple, ceux du département des ventes voient un lien vers les enregistrements financiers dans le menu principal, mais quand ils cliquent dessus, rien ne se passe. Il en est ainsi car AFAIK il n'y a aucun moyen efficace d'interroger les privilèges de l'utilisateur en utilisant acts_as_authenticated.

Je veux changer cela de deux façons:

  1. Je veux présenter l'autorisation à grain plus fin. Actuellement, l'autorisation est effectuée au niveau du contrôleur. Je veux faire cela au niveau de l'action ou du modèle. Par exemple, je souhaite que ceux du département des ventes puissent créer et mettre à jour les paiements, mais pas les supprimer. Je veux être en mesure d'interroger efficacement les privilèges de l'utilisateur, afin de pouvoir supprimer les liens inutiles (et confus) de l'interface.

Selon vous, quelle est la façon la plus élégante de mettre en œuvre cette solution?

Les réponses spécifiques à Rails ne sont pas nécessaires, je veux juste 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 initiale, que je pense est pas la meilleure façon de résoudre ce:

 
+------------+------------+---------+ 
| 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 | 
+------------+----------+-------+--------+------+--------+--------+ 

Répondre

3

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

  1. relation d'un utilisateur au système dans son ensemble
  2. relation d'un utilisateur à une sorte d'entités (par exemple (par exemple, être administrateur du système.). être un modérateur de commentaires)
  3. relation d'un utilisateur à une entité particulière (par exemple être propriétaire d'une ressource)
  4. une autre relation complexe (par exemple être un ami d'un utilisateur qui est propriétaire de une ressource)
  5. cet utilisateur a un ou plusieurs attributs ou répond à un message dans certains r moyen (par ex. être un adolescent)

Un système d'autorisation à granularité très fine devrait vous permettre de définir le rôle d'un utilisateur selon l'un des critères mentionnés ci-dessus. En outre, il devrait vous permettre de définir plus d'un rôle pour un utilisateur. (Les formes les plus simples de plugins 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 s'exécuter) basé sur le fait que l'utilisateur s'intègre dans un rôle (ensemble de rôles) ou non. Pour appliquer ce mécanisme, nous devons trouver les points où l'autorisation doit avoir lieu et sélectionner les rôles pour lesquels le code devrait ou ne devrait pas être exécuté. Dans Rails, la façon dont je travaille est de définir les rôles au niveau du modèle et de laisser le mécanisme d'autorisation (définir les rôles autorisés pour les parties du code que je veux autoriser et demander si l'utilisateur actuel a le rôle autorisé pour exécuter la pièce) entièrement pour les contrôleurs/vues. Pour cela, j'utilise tweaked rails-authorization-plugin qui a toutes les possibilités que je viens de mentionner (différents types de rôles, plusieurs rôles pour un utilisateur, autorisation sur le contrôleur et le niveau de vue).

0

vous devrez peut-être introduire la notion de «points de fonction» ou «caractéristiques» dans votre modèle en tant que points de contrôle pour acc ess; une 'feature' peut avoir une 'fonction parent' optionnelle pour former une hiérarchie. Vous arrivez à décider ce qui est et n'est pas 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 à accéder.

une situation/solution similaire est décrite here

0

de vos deux propositions, la première option semble un peu mieux car il vous permet d'ajouter des actions qui peuvent ne pas être des actions au niveau modèle. Je suppose que vous rencontrerez un cas où le deuxième modèle ne suffit pas, et vous devrez soit changer le schéma ou commencer à saupoudrer la logique des autorisations dans votre application (ex.« Les utilisateurs sans « créer » l'accès aussi ne peut pas exécuter la méthode xxx »)

Je pense que la raison pour laquelle la solution ne semble pas très sec est qu'il ya répétition:

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

En ce qui concerne # 1, il serait logique de créer une table des départements et donner à chaque département un identifiant. En ce qui concerne le numéro 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 les utilisateurs et les fonctions. Les fonctions auraient alors une relation un-à-plusieurs avec les actions/contrôleurs qu'elles autorisent. Cela vous permettrait, avec une répétition minimale, de dire des choses comme «la comptabilité et les ventes devraient être en mesure de lire toutes les tables financières."

+0

J'ai déjà une table departments et une table users_departments. J'ai simplifié le tableau d'exemple pour la brièveté. –

Questions connexes