J'examine la conception de mon interface et j'ai du mal à décider quelle est la façon la plus "correcte" d'implémenter le contrôle d'accès basé sur les rôles, étant donné un user
et un subject
auxquels user
ils aimeraient accéder.
Pour autant que je puisse voir, j'ai trois options de base (avec une quatrième étant une bâtardisation des trois premiers et une cinquième étant un ajustement du quatrième):
- Recherchez le
subject
avec une liste d'autorisations que leuser
a -subject.allowAccess(user.getPermissionSet)
- Recherchez le
user
avec une liste d'autorisations que lesubject
requiert -user.hasPermissionTo(subject.getRequiredPermissions())
- Interrogez un tiers pour localiser les intersections des autorisations -
accessController.doPermissionSetsIntersect(subject.permissionSet, user.getPermissionSet())
- Interrogez le
subject
/user
tout en déléguant la "décision" à une classe tierce - Avoir la
user
tentative d'accéder àsubject
et lancer une erreur si l'accès n'est pas autorisé
Je me penche vers l'option quatre - Avoir le subject
contient un accessController
champ, où les appels à subject.userMayAccess(User user)
déléguer l'opération à la:
class Subject {
public function display(user) {
if(!accessController.doPermissionSetsIntersect(this.permissionSet, user.getPermissionSet())) {
display403(); //Or other.. eg, throw an error..
}
}
}
.. mais cela soulève d'autres questions:
- devrait
accessController
être un champ vs une classe statique ..? - Faut-il
subject
savoir quelles autorisations sont nécessaires pour pouvoir le voir? - où le principe de moindre connaissance entre-t-il en jeu ici, en ce qui concerne l'appel
subject.display()
? Les appelants devraient-ilssubject.display()
savoir que le contrôle d'accès est en vigueur? (où sesubject.display()
trouve une "méthode modèle" finale) - avoir
subject.display()
gérer le contrôle d'accès, levant une exception où l'utilisateur n'a pas l'autorisation requise?
Quelle serait la «meilleure pratique» dans cette situation? Où la responsabilité d'effectuer les contrôles devrait-elle réellement se produire?
Comme il s'agit en quelque sorte d'un exercice académique qui progressera ensuite dans la mise en œuvre, des références aux modèles de conception seraient appréciées.
Je pense que votre option 3 est la plus proche, mais au lieu d'interroger le
user
etsubject
sur leurs jeux d'autorisations, vous devez passer leuser
etsubject
au contrôleur d'accès.Le contrôleur d'accès devrait être responsable à la fois de l'obtention des jeux d'autorisations et de la vérification si l'accès est suffisant. De cette façon, vous isolez à la fois la logique de stockage et la logique de vérification dans votre contrôleur d'accès, distinctes de l'utilisateur et du sujet.
L'autre élément qui manque peut-être à votre exemple est quelle opération est effectuée. Certains utilisateurs peuvent avoir le droit de lire certaines données , mais pas à mettre à jour, supprimer, exécuter, etc. Donc , vous pourriez avoir une
checkAccess
méthode sur le contrôleur d'accès à trois paramètres:user
,subject
,operation
. Vous pouvez également fournir des informations supplémentaires decheckAccess
retour pour renvoyer des informations sur les raisons pour lesquelles l'accès n'a pas été accordé.Par exemple, déléguer tout cela au contrôleur d'accès ultérieurement vous permet de remplacer la façon dont vos autorisations sont représentées. Vous pouvez commencer par le contrôle d'accès basé sur les rôles et passer ultérieurement aux revendications. Vous pouvez stocker des autorisations dans une structure simple pour commencer, puis ajouter des groupes / rôles hiérarchiques et des opérations autorisées sur différents types de sujets. Ne pas mettre vos jeux d'autorisations dans l'interface permet d'activer cela.
Que vous utilisiez AOP ou un code standard pour le brancher est, à mon avis, moins important.
la source