Quelle est la meilleure façon de gérer plusieurs types d'autorisations?

Je rencontre souvent le scénario suivant où j'ai besoin d'offrir de nombreux types d'autorisations. J'utilise principalement ASP.NET / VB.NET avec SQL Server 2000.

Scénario

Je veux offrir un système de permission dynamique qui peut fonctionner sur différents paramètres. Disons que je veux donner à un département ou à une personne spécifique l'accès à une application. Et prétendre que nous avons un certain nombre d'applications qui ne cesse de croître.

Dans le passé, j'ai choisi l'une des deux façons suivantes que je sais faire.

1) Utilisez une seule table de permission avec des colonnes spéciales qui sont utilisées pour déterminer comment appliquer les paramètres. Les colonnes spéciales de cet exemple sont TypeID et TypeAuxID. Le SQL ressemblerait à ceci.

SELECT COUNT(PermissionID)
FROM application_permissions
WHERE
(TypeID = 1 AND TypeAuxID = @UserID) OR
(TypeID = 2 AND TypeAuxID = @DepartmentID)
AND ApplicationID = 1

2) Utilisez une table de correspondance pour chaque type d'autorisation, puis joignez-les tous ensemble.

SELECT COUNT(perm.PermissionID)
FROM application_permissions perm
LEFT JOIN application_UserPermissions emp
ON perm.ApplicationID = emp.ApplicationID
LEFT JOIN application_DepartmentPermissions dept
ON perm.ApplicationID = dept.ApplicationID
WHERE [email protected]
  AND ([email protected] OR [email protected] OR
 (emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1
ORDER BY q.QID ASC

Mes pensées

J'espère que les exemples ont du sens. Je les ai bricolé ensemble.

Le premier exemple nécessite moins de travail, mais aucun d'eux ne semble être la meilleure réponse. Y a-t-il une meilleure façon de gérer cela?

0

5 Réponses

Honnêtement, les fonctionnalités ASP.NET Membership / Roles fonctionneraient parfaitement pour le scénario que vous avez décrit. Écrire vos propres tables / procs / classes est un excellent exercice et vous pouvez obtenir un très bon contrôle sur les détails, mais après avoir fait cela moi-même, j'ai conclu qu'il est préférable d'utiliser simplement les choses. NET intégré. Beaucoup de code existant est conçu pour contourner ce problème, ce qui est très bien. Rédaction à partir de zéro m'a pris environ 2 semaines et il était loin d'être aussi robuste que. NET. Vous devez coder tant de merde (récupération de mot de passe, verrouillage automatique, cryptage, rôles, une interface d'autorisation, des tonnes de procs, etc) et le temps pourrait être mieux passé ailleurs.

Désolé si je n'ai pas répondu à votre question, je suis comme le gars qui dit d'apprendre C# quand quelqu'un pose une question vb.

0
ajouté

Une approche que j'ai utilisée dans diverses applications est d'avoir une classe générique PermissionToken qui a une propriété Value modifiable. Ensuite, vous interrogez l'application demandée, elle vous indique les PermissionTokens nécessaires pour l'utiliser.

Par exemple, l'application Expédition peut vous indiquer qu'elle a besoin:

new PermissionToken()
{
    Target = PermissionTokenTarget.Application,
    Action = PermissionTokenAction.View,
    Value = "ShippingApp"
};

Cela peut évidemment être étendu à Create, Edit, Delete etc et, en raison de la propriété Value personnalisée, toute application, module ou widget peut définir ses propres autorisations requises. YMMV, mais cela a toujours été une méthode efficace pour moi que j'ai trouvé à bien évoluer.

0
ajouté

En plus des solutions de John Downey et de jdecuyper, j'ai ajouté un bit "Explicit Deny" à la fin / au début du bitfield, afin que vous puissiez effectuer des permissions additives par groupe, appartenance au rôle, puis soustraire les permissions basées sur le refus explicite entrées, un peu comme NTFS fonctionne, à la manière des permissions.

0
ajouté

Je suis d'accord avec John Downey.

Personnellement, j'utilise parfois une énumération signalée d'autorisations. De cette façon, vous pouvez utiliser les opérations sur les bits AND, OR, NOT et XOR sur les éléments de l'énumération.

"[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}"

Then, you can combine several permissions using the AND bitwise operator.

For example, if a user can view & edit users, the binary result of the operation is 0000 0011 which converted to decimal is 3.
You can then store the permission of one user into a single column of your DataBase (in our case it would be 3).

Inside your application, you just need another bitwise operation (OR) to verify if a user has a particular permission or not.

0
ajouté
le problème que j'ai trouvé avec cette approche est qu'il est vraiment facile de manquer de rôles en utilisant cette approche. Comme vous pouvez le voir, 6 rôles ont une valeur de 2 ^ 6 = 64, alors que 31 rôles auront 2 ^ 31 = 2 147 483 647 qui est la valeur max int. Ainsi, dans T-SQL, le plus gros type de données pouvant être utilisé est bigint (2 ^ 63). Bien sûr, vous pouvez utiliser le type varchar, mais je préfère utiliser la solution de John Downey quand j'ai beaucoup de rôles.
ajouté l'auteur Maksim Vi., source

La façon dont je vais généralement coder les systèmes d'autorisation est d'avoir 6 tables.

  • Utilisateurs - c'est assez simple c'est votre table d'utilisateurs typique
  • Groupes - ce serait synonyme de vos départements
  • Rôles - ceci est une table avec toutes les autorisations généralement aussi y compris un nom lisible par l'homme et une description
  • Users_have_Groups - c'est une table plusieurs-à-plusieurs des groupes auxquels un utilisateur appartient
  • Users_have_Roles - une autre table plusieurs-à-plusieurs des rôles assignés à un utilisateur individuel
  • Groups_have_Roles - la table finale many-to-many des rôles de chaque groupe

Au début d'une session d'utilisateurs, vous exécutez une logique qui extrait tous les rôles qu'ils ont attribués, que ce soit un répertoire ou un groupe. Ensuite, vous codez sur ces rôles en tant que vos autorisations de sécurité.

Comme je l'ai dit, c'est ce que je fais habituellement, mais votre millage peut varier.

0
ajouté