web-dev-qa-db-fra.com

Contrôle d'accès basé sur les rôles et les autorisations

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 à grain fin (" Modifier la ressource X "," Accéder à la page du tableau de bord ", etc.). Un rôle sera une collection de 1+ autorisations. 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 selon les besoins.

Mes préoccupations:

(1) Qu'est-ce qui est si "mauvais" dans la vérification des rôles pour le contrôle d'accès? Quels sont les avantages obtenus en vérifiant les autorisations à la place? 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 attribuer directement 1+ autorisations aux utilisateurs directement? Quelle concrète valeur d'abstraction les rôles offrent-ils (quelqu'un peut-il donner des exemples spécifiques)?

45
smeeb

(1) Qu'est-ce qui est si "mauvais" dans la vérification des rôles pour le contrôle d'accès? Quels sont les avantages obtenus en vérifiant les autorisations à la place?

Au moment de la vérification, le code appelant n'a besoin que de savoir "l'utilisateur X a-t-il la permission d'effectuer l'action Y?".
Le code appelant ne se soucie pas et ne doit pas être au courant des relations entre les rôles et les autorisations.

La couche d'autorisation vérifiera ensuite si l'utilisateur a cette autorisation, généralement en vérifiant si le rôle de l'utilisateur a 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'appel, vous établissez implicitement des relations d'autorisation de rôle et injectez une logique d'autorisation dans le code appelant, violant ainsi la séparation des préoccupations.

Si vous décidez plus tard que le rôle foo ne devrait pas avoir l'autorisation baz, vous devrez modifier chaque code qui vérifie si l'utilisateur est un foo.

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

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

Supposons que vous ajoutez une nouvelle fonctionnalité qui permet à un utilisateur de modifier certains paramètres. Cette fonctionnalité ne doit être accessible qu'aux administrateurs.

Si vous stockez des autorisations par utilisateur, vous devrez trouver tous les utilisateurs de votre base de données dont vous savez qu'ils sont des administrateurs (Si vous ne stockez pas d'informations de rôle pour les utilisateurs, comment sauriez-vous même quels utilisateurs sont des administrateurs? ), et ajoutez cette autorisation à leur liste d'autorisations.

Si vous utilisez des rôles, vous n'avez qu'à ajouter l'autorisation au rôle Administrator, qui est à la fois plus facile à exécuter, plus économe en espace et moins sujet aux erreurs.

66
Rotem

En réponse à votre première question, le plus gros problème avec la vérification 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. Par exemple, un développeur peut avoir accès au portail des développeurs sur l'intranet de l'entreprise, ce qui est probablement également une autorisation détenue par son responsable. Si un utilisateur tente ensuite d'accéder au portail des développeurs, vous obtiendrez une vérification similaire à:

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

(Une déclaration switch dans la langue de votre choix serait mieux, mais pas particulièrement bien rangée)

Plus une autorisation est courante ou largement détenue, plus vous devez vérifier les rôles d'utilisateur pour vous assurer que quelqu'un est en mesure d'accéder à un système donné. Cela entraînerait également le problème suivant: chaque fois que vous modifiez des autorisations pour un rôle, vous devez modifier la vérification pour refléter cela. Dans un grand système, cela deviendrait très lourd et très rapidement.

Si vous vérifiez simplement que l'utilisateur a l'autorisation qui lui permet d'accéder au portail des développeurs, par exemple, peu importe le rôle qu'il détient, l'accès lui sera accordé.

Pour répondre à votre deuxième question, la raison pour laquelle vous avez des rôles est qu'ils sont faciles à modifier et à distribuer des "packages" d'autorisations. Si vous avez un système qui a des centaines de rôles et des milliers d'autorisations, l'ajout d'un nouvel utilisateur (par exemple un nouveau responsable RH) vous obligerait à passer par et à leur donner toutes les autorisations que les autres responsables RH détiennent. Non seulement cela serait fastidieux, mais il est sujet à des erreurs s'il est fait manuellement. Comparez cela à l'ajout simple du rôle "HR manager" au profil d'un utilisateur, ce qui lui donnera le même accès que tous les autres utilisateurs avec ce rôle.

Vous pouvez faire valoir que vous pouvez simplement cloner un utilisateur existant (si votre système le prend en charge), mais bien que cela accorde à l'utilisateur les autorisations appropriées pour ce moment, il peut être tentant d'ajouter ou de supprimer une autorisation pour tous les utilisateurs à l'avenir. difficile. Un exemple de scénario pour cela est si peut-être dans le passé le personnel des RH était également en charge de la paie, mais plus tard, l'entreprise devient suffisamment importante pour embaucher du personnel spécifiquement pour gérer la paie. Cela signifie que les RH 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 des RH, vous devrez parcourir manuellement et vous assurer que vous supprimez l'autorisation correcte, ce qui introduit la possibilité d'erreur utilisateur. L'autre problème avec cela est qu'il ne se modifie tout simplement pas; à mesure que vous gagnez de plus en plus d'utilisateurs dans un rôle donné, cela rend la modification d'un rôle beaucoup plus difficile. Comparez cela à l'utilisation de rôles, où vous n'auriez qu'à modifier le rôle primordial en question pour supprimer l'autorisation, qui serait reflétée par chaque utilisateur qui détient ce rôle.

20
Matt Champion