Les vérifications des autorisations des utilisateurs doivent-elles avoir lieu dans le modèle ou le contrôleur? Et qui devrait gérer les vérifications des autorisations, l'objet utilisateur ou un assistant de gestion des utilisateurs?
Où cela devrait-il arriver?
Vérification dans le contrôleur:
class MyController {
void performSomeAction() {
if (user.hasRightPermissions()) {
model.someAction();
}
}
...
Avoir les vérifications dans le contrôleur aide à rendre les modèles des actions simples, afin que nous puissions garder toute la logique pour les contrôleurs.
Vérification du modèle:
class MyModel {
void someAction() {
if (user.hasRightPermissions()) {
...
}
}
...
En mettant les vérifications dans le modèle, nous compliquons le modèle, mais nous veillons également à ne pas autoriser accidentellement les utilisateurs à faire des choses qu'ils ne sont pas censés faire dans le contrôleur.
Et par qui?
Une fois que nous nous sommes installés, qui devrait faire les vérifications? L'utilisateur?
Class User {
bool hasPermissions(int permissionMask) {
...
}
...
Mais ce n'est pas vraiment la responsabilité de l'utilisateur de savoir ce qu'il peut accéder, alors peut-être une classe d'aide?
Class UserManagement {
bool hasPermissions(User user, int permissionMask) {
...
}
...
Je sais qu'il est courant de poser juste une seule question dans, eh bien, une question, mais je pense qu'on peut y répondre bien ensemble.
la source
La sécurité est une préoccupation transversale, elle doit donc être mise en œuvre en plusieurs couches. Ce qui suit est un exemple pour MVC mais le concept s'applique à d'autres architectures et / ou modèles, il vous suffit d'identifier les points d'application.
Où cela devrait-il arriver?
Les vues peuvent contenir des éléments d'interface utilisateur (widgets, boutons, menus, etc.) qui doivent être affichés ou non pour certains utilisateurs, en fonction de leurs autorisations. Cela pourrait être une responsabilité du moteur de vue , car vous ne voulez pas que chaque vue gère cela seule. Selon le type d'éléments que vous accordez, vous déplacez à froid cette responsabilité dans un autre endroit. Par exemple, pensez à un menu dans lequel certains éléments doivent être affichés et d'autres non. Les éléments peuvent être implémentés sous forme de liste quelque part et filtrer cette liste en fonction des autorisations, puis la transmettre à la vue.
Les contrôleurs répondent aux demandes, donc si un utilisateur n'a pas la permission d'exécuter une action, elle doit être vérifiée avant que l'action soit invoquée, déplaçant la responsabilité vers le demandeur de l' action au lieu de la conserver dans le contrôleur. Cela a l'avantage de garder votre contrôleur propre et si quelque chose change dans les autorisations, vous n'avez pas à passer au crible vos contrôleurs pour appliquer ces changements.
Les ressources sont affichées en fonction des autorisations. Cela se fait normalement au niveau de la base de données , car vous ne voulez pas tout extraire de la base de données, puis appliquer des autorisations.
Comme vous pouvez le voir, selon ce que vous souhaitez autoriser, il existe différents endroits où cela doit être fait. Le but est d'être aussi discret que possible, de sorte que lorsque votre politique de sécurité change, vous pouvez facilement l'appliquer, de préférence sans altérer le code de votre application. Cela peut ne pas être valable pour les petites applications, où l'ensemble d'autorisations est assez petit et ne change pas très souvent. Cependant, dans les applications d'entreprise, l'histoire est assez différente.
Qui devrait le faire?
Clairement pas le modèle. Chaque couche doit avoir un point d'application qui gère l'autorisation. Le texte en italique ci-dessus met en évidence le point d'application possible pour chaque niveau.
Jetez un oeil à XACML . Vous n'êtes pas obligé de l'implémenter tel quel, mais cela vous donnera quelques indications que vous pourriez suivre.
la source
J'utilise le schéma suivant. Il convient de dire que la plupart des vérifications des autorisations des utilisateurs peuvent être divisées en deux cas généraux:
L'accès à l'action du contrôleur sans vérification des attributs est généralement implémenté dans les frameworks MVC. C'est simple du tout: vous définissez des règles, vos utilisateurs ont un rôle. Vous vérifiez simplement que l'utilisateur est autorisé à effectuer une recherche de son rôle dans les règles.
L'accès des utilisateurs à un modèle particulier doit être défini dans le modèle. (L'acteur est une classe d'utilisateurs de base. Supposons qu'il puisse s'agir d'un client, d'un vendeur ou d'un invité.)
Placer cette logique dans le modèle apporte un certain profit. La méthode de contrôle d'accès peut être héritée, vous n'avez pas besoin de créer de classes supplémentaires, vous pouvez utiliser les avantages généraux de la POO.
Ensuite, pour simplifier la vérification d'accès, nous prenons certaines hypothèses qui sont presque toujours déjà implémentées pour la simplicité et le bon style:
Avec ces hypothèses, les actions qui utilisent l'ID de modèle peuvent être associées à une instance de modèle particulière. En fait, la plupart des actions peuvent facilement être transformées et déplacées pour correspondre aux hypothèses énoncées ci-dessus.
Ensuite, une classe de contrôleur abstrait de base doit être définie et héritée.
Vous pouvez appeler la méthode SomeController :: checkModelAccess ($ id) lorsque vous construisez vos menus et décidez d'afficher ou non un lien.
la source
Dans le modèle et la vue
Dans la vue - car l'interface utilisateur ne doit pas afficher les éléments d'interface utilisateur qui sont limités à l'utilisateur actuel
(comme, par exemple, le bouton "Supprimer" devrait être affiché aux personnes disposant des autorisations appropriées)
Dans le modèle - parce que votre application a probablement une sorte d'API, non? L'API doit également vérifier les autorisations et probablement réutiliser le modèle.
(comme, disons, vous avez le bouton "Supprimer" dans l'interface utilisateur et la méthode API "http: / server / API / DeleteEntry / 123" en même temps
la source
MVC est un modèle de présentation. En tant que tel, la vue et le contrôleur ne devraient avoir que des responsabilités concernant la présentation. Certaines autorisations s'appliquent à la présentation, comme un mode expert, des fonctionnalités d'interface utilisateur expérimentales ou différentes conceptions. Celles-ci peuvent être gérées par le contrôleur MVC.
De nombreux autres types d'autorisations s'appliquent à plusieurs couches de l'application. Par exemple, si vous souhaitez avoir des utilisateurs qui ne peuvent voir que les données et ne pas changer les choses:
Il y a une certaine duplication dans cette approche. Mais comme la présentation est généralement volatile, on peut faire un bon argument pour vérifier l'autorisation dans la partie généralement plus stable de l'application, même si cela signifie des vérifications redondantes au cas où la couche de présentation fonctionne comme prévu.
la source