Rôle vs contrôle d'accès basé sur les autorisations

45

J'essaie de comprendre le compromis inhérent entre les rôles et les autorisations en matière de contrôle d'accès (autorisation).

Commençons par une donnée: dans notre système, une autorisation sera une unité d’accès fine (" Editer la ressource X ", " Accéder à la page du tableau de bord ", etc.). Un rôle sera une collection d'autorisations 1+. Un utilisateur peut avoir 1+ rôles. Toutes ces relations (utilisateurs, rôles, autorisations) sont toutes stockées dans une base de données et peuvent être modifiées à la volée et au besoin.

Mes préoccupations:

(1) Quel est le problème avec la vérification des rôles pour le contrôle d'accès? Quels sont les avantages tirés de la vérification des autorisations? En d'autres termes, quelle est la différence entre ces deux extraits ci-dessous:

if(SecurityUtils.hasRole(user)) {
    // Grant them access to a feature
}

// vs.
if(SecurityUtils.hasPermission(user)) {
    // Grant them access to a feature
}

Et:

(2) Dans ce scénario, quelle valeur utile les rôles fournissent-ils même? Ne pourrions-nous pas simplement attribuer une ou plusieurs autorisations directement aux utilisateurs? Quelle valeur concrète de l'abstraction offre-t-il aux rôles (quelqu'un peut-il donner des exemples spécifiques)?

smeeb
la source
2
Quelques points: (1) un seul utilisateur peut avoir plusieurs rôles, (2) vous pouvez examiner les listes de contrôle d'accès (ACL), par exemple. vous souhaiterez peut-être pouvoir accorder "Accéder à la page du tableau de bord" à seulement un sous-ensemble de pages de tableau de bord (s'il en existe plusieurs).
Matthieu M.

Réponses:

63

(1) Quel est le problème avec la vérification des rôles pour le contrôle d'accès? Quels sont les avantages tirés de la vérification des autorisations?

Au moment de la vérification, le code appelant doit seulement savoir "l'utilisateur X est-il autorisé à effectuer l'action Y?" .
Le code d'appel ne se soucie pas et ne devrait pas être conscient des relations entre les rôles et les autorisations.

La couche d'autorisation vérifie ensuite si l'utilisateur dispose de cette autorisation, généralement en vérifiant si le rôle de l'utilisateur dispose de cette autorisation. Cela vous permet de modifier la logique d'autorisation sans mettre à jour le code appelant.

Si vous vérifiez directement le rôle sur le site d'appels, vous créez implicitement des relations de permission entre les rôles et injectez une logique d'autorisation dans le code de l'appelant, violant ainsi la séparation des problèmes.

Si vous décidez plus tard que ce rôle foone doit pas avoir d’autorisation baz, vous devrez changer tous les codes qui vérifient si l’utilisateur est a foo.

(2) Dans ce scénario, quelle valeur utile les rôles fournissent-ils même? Ne pourrions-nous pas simplement attribuer une ou plusieurs autorisations directement aux utilisateurs? Quelle valeur concrète de l'abstraction offre-t-il aux rôles (quelqu'un peut-il donner des exemples spécifiques)?

Les rôles représentent conceptuellement une collection nommée d'autorisations.

Supposons que vous ajoutiez une nouvelle fonctionnalité permettant à un utilisateur de modifier certains paramètres. Cette fonctionnalité ne devrait être disponible que pour les administrateurs.

Si vous stockez des autorisations par utilisateur, vous devez rechercher tous les utilisateurs de votre base de données dont vous savez en quelque sorte qu'il s'agit d'administrateurs (si vous ne stockez pas les informations de rôle pour les utilisateurs, comment sauriez-vous même quels utilisateurs sont des administrateurs?) , Puis ajoutez cette autorisation à leur liste d'autorisations.

Si vous utilisez des rôles, il vous suffit d'ajouter l'autorisation au Administratorrôle, qui est à la fois plus facile à exécuter, plus efficace en termes d'espace et moins sujet aux erreurs.

Rotem
la source
Euh La couche d'authentification vérifiera que l'utilisateur est celui qui prétend l'être; la couche qui vérifie les fonctions / données auxquelles un tel utilisateur peut accéder est la couche autorisation
SJuan76
4
Cela devrait être une lecture obligatoire pour tous les programmeurs. Excellent.
Kosta Kontos
2
Simple, concis et pertinent - bat un chapitre entier d'un livre quelque part. Merci.
Dan Nissenbaum
2
Commentaire pour plus de clarté (et corrigez-moi si je me trompe): Une authorization layerexpression probable ne signifie rien de plus que simplement avoir la définition de la fonction (c.-à-d.) user->hasPermission(SOME_PERMISSION)Vérifier d'abord les rôles de l'utilisateur en interne, puis vérifier si l'un des rôles inclut / exclut la fonction donnée. autorisation. Par exemple, the calling codevérifiez si une page donnée est visible pour l'utilisateur et qu'elle appelle user->hasPermission(VIEW_GIVEN_PAGE), et authorization layerconsiste en la définition de la hasPermissionfonction qui vérifie les rôles comme ci-dessus.
Dan Nissenbaum
1
@ DanNissenbaum Ouais, on dirait que vous avez bien compris, cela peut être aussi simple que de vérifier si le rôle de l'utilisateur dispose de cette autorisation. Cela pourrait aussi être plus que cela. Par exemple, vous avez peut-être la possibilité de suspendre temporairement un utilisateur et, dans ce cas, de hasPermissionvérifier usersRole.HasPermission(VIEW_GIVEN_PAGE) && !user.Suspended. Le fait est que tout se fait au même endroit et non dans le code consommateur (appelant).
Rotem
18

En réponse à votre première question, le plus gros problème en vérifiant qu'un utilisateur a un rôle plutôt qu'une autorisation spécifique est que les autorisations peuvent être détenues par plusieurs rôles. À titre d’exemple, un développeur peut accéder au portail de développement sur l’intranet de la société, qui est probablement aussi une autorisation détenue par son responsable. Si un utilisateur tente alors d'accéder au portail de développeur, vous devez effectuer une vérification semblable à:

if(SecurityUtils.hasRole(developer)) {
    // Grant them access to a feature
} else if(SecurityUtils.hasRole(manager)) {
    // Grant them access to a feature
} else if...

(Une switchdéclaration dans la langue de votre choix serait préférable, mais pas très soignée)

Plus une autorisation est courante ou répandue, plus vous aurez besoin de vérifier les rôles d'utilisateur pour vous assurer que quelqu'un est capable d'accéder à un système donné. Cela poserait également le problème suivant: chaque fois que vous modifiez les autorisations pour un rôle, vous devez modifier la vérification en conséquence. Dans un grand système, cela deviendrait très difficile à manier très rapidement.

Si vous vérifiez simplement que l'utilisateur dispose de l'autorisation lui permettant d'accéder au portail de développeur, peu importe le rôle qu'il détient, l'accès lui sera accordé.

Pour répondre à votre deuxième question, vous avez des rôles parce qu’ils permettent de modifier et de distribuer facilement des "packages" d’autorisations. Si votre système possède des centaines de rôles et des milliers d'autorisations, l'ajout d'un nouvel utilisateur (un nouveau responsable des ressources humaines, par exemple) vous obligerait à passer par toutes les autorisations dont disposent les autres responsables des ressources humaines. Non seulement cela serait fastidieux, mais il est sujet à des erreurs s'il est fait manuellement. Comparez cela à simplement ajouter le rôle "HR Manager" au profil d'un utilisateur, ce qui leur donnera le même accès que tous les autres utilisateurs dotés de ce rôle.

Vous pouvez faire valoir que vous pouvez simplement cloner un utilisateur existant (si votre système le permet), mais bien que cela accorde à l'utilisateur les autorisations appropriées pour l'instant, il peut être tentant d'ajouter ou de supprimer une autorisation pour tous les utilisateurs à l'avenir. difficile. Un exemple de scénario: si le personnel des ressources humaines était peut-être également responsable de la paie, mais que l'entreprise devient suffisamment nombreuse pour engager du personnel spécifiquement chargé de la gestion de la masse salariale. Cela signifie que les ressources humaines n'ont plus besoin d'accéder au système de paie, de sorte que l'autorisation peut être supprimée. Si vous avez 10 membres différents de HR, vous devrez passer manuellement et vous assurer que vous supprimez l'autorisation appropriée, ce qui introduit la possibilité d'erreur d'utilisateur. L'autre problème avec ceci est que cela n'échelle tout simplement pas; à mesure que de plus en plus d'utilisateurs gagnent un rôle donné, il est beaucoup plus difficile de modifier un rôle. Comparez cela à l'utilisation de rôles, où il vous suffirait de modifier le rôle global en question pour supprimer l'autorisation, ce qui serait reflété par chaque utilisateur qui détient ce rôle.

Matt Champion
la source
bon exemple, merci!
Frank