En règle générale, je place les décisions d'autorisation dans mes contrôleurs côté serveur. Ces derniers ont été des points de terminaison RESTful récemment, mais je pense qu'il en va de même pour les architectures de type MVC. Pour les besoins de l'argument, supposons qu'il s'agit d'une autorisation basée sur les rôles. Une méthode protégée sera annotée ou fera des vérifications et retournera 403 si nécessaire.
Maintenant, étant donné que l'autorisation est en fait une règle commerciale - "seuls les administrateurs peuvent lister X" par exemple, je pense qu'ils devraient être poussés vers le bas d'une couche. Lorsqu'un contrôleur demande à la couche métier d'effectuer l'opération, le service ou la couche métier informe le contrôleur qu'il n'est pas autorisé.
Est-ce une approche raisonnable? Y a-t-il des inconvénients à cela?
Je déteste avoir un AuthorisationService qui contient essentiellement un tas de règles codées procédurales statiques pour le faire, mais il est peut-être logique de garder toute la logique d'accès en un seul endroit. Est-ce une préoccupation transversale qui devrait être séparée?
Je demande donc si quelqu'un a fait cela et comment il y est parvenu de manière propre ou s'il existe de bonnes ressources que je pourrais lire. J'utilise Java fwiw mais c'est une question indépendante du langage.
J'ai vérifié les questions connexes ici et elles sont très minces sur le terrain et les réponses. Par exemple: Validation et autorisation dans les modèles de domaine et transfert à MVC via une couche de service
Je lis les documents de sécurité du printemps qui présentent de bons arguments pour que ce soit une préoccupation transversale, mais je crains que ce ne soit que la "voie du printemps" et j'aimerais des perspectives plus larges. Il lie également votre application à un cadre spécifique.
Réponses:
Il est recommandé d'exposer uniquement les options pour lesquelles un utilisateur est autorisé.
Cela oblige l'autorisation à être une préoccupation transversale. La "Vue" doit savoir ce qu'un utilisateur est autorisé à faire avant de pouvoir créer des options et des menus à afficher.
Le serveur principal ne doit pas faire confiance au serveur frontal pour prendre des décisions de sécurité, il doit donc vérifier l'autorisation lui-même.
Il peut y avoir des règles commerciales qui affectent l'autorisation en fonction des données, par exemple "Seuls les utilisateurs dont le solde est supérieur à 5 000 $ peuvent invoquer un transfert en devises étrangères" ou "Seul un utilisateur situé au siège social peut consulter ces comptes". Une logique d'autorisation est donc requise dans la logique métier.
Il y a également des autorisations techniques à considérer - qui est autorisé à consulter les journaux, qui peut sauvegarder / restaurer la base de données, etc.
Ainsi, à la fin, chaque composant de votre système peut avoir des exigences de sécurité et / ou d'autorisation spécifiques, dans la pratique, il est presque impossible de les regrouper dans une "couche d'autorisation" distincte.
la source
Je pense que c'est une approche absolument raisonnable d'implémenter l'autorisation dans votre couche Service. Vous devez protéger votre service contre les activités non autorisées (en particulier les modifications de données). Votre couche de service peut résider dans une bibliothèque et être utilisée par différentes couches de présentation (vous pouvez avoir différentes applications d'interface utilisateur, qui utilisent la même couche de service). Et vous ne pouvez pas compter sur le fait que des couches de présentation spécifiques effectuent la validation nécessaire. Ceci est particulièrement important si vous décidez par la suite de déplacer votre couche Service vers le processus séparé (par exemple en suivant l'approche SOA).
Maintenant, comment y parvenir de manière "propre". Je n'aime pas l'idée d'alterner la logique métier avec des vérifications d'autorisation, donc une implémentation spécifique d'une approche de programmation orientée aspect pourrait aider: cela pourrait être de décorer des méthodes de service avec des attributs spéciaux ou d'utiliser des proxys dynamiques avec des interceptions.
Et surtout, je dois admettre que dans des projets très simples, peut-être, vous pourriez vivre sans validations séparées, juste pour vous simplifier la vie. Mais il est important de ne pas manquer le moment où le «projet simple» a commencé à devenir le «projet complexe».
la source
J'aime pousser les contrôles d'autorisation aussi bas que possible! (Mais pas plus loin!)
Vous êtes toujours libre d'écrire des tests d'autorisation automatisés contre des couches "au-dessus" de cela. Et certaines règles peuvent uniquement être applicables ou avoir un sens dans les couches supérieures comme votre couche de service (CanView / CanSerialize?). Mais, je pense généralement que la stratégie d'autorisation la plus sûre est également la stratégie "DRY-est": Gardez l'autorisation aussi bas que possible, dans le code le plus "commun" ou "partagé" que vous pouvez (sans trop compliquer les règles d'authentification).
Pensez à l'alternative. Si vos règles d'autorisation sont testées et appliquées uniquement dans la couche de service, laissant vos objets de domaine pauvres se plier aux volontés d'un service de mauvaise humeur, vous devrez souvent appliquer chaque règle individuelle plus d'une fois, dans plusieurs objets et plusieurs place dans chaque objet, et dans un code plus compliqué.
De plus, lorsque votre équipe d'analyse engage une société de conseil pour rédiger des services de reporting à l'aide de vos objets de domaine, vous ne voulez pas avoir à faire confiance à ces développeurs! (Ou peu importe. Vous créez des services ou des appels supplémentaires sur les mêmes objets pour une raison quelconque .) Vous ne voudrez pas ouvrir le grand livre des règles de gestion et espérer appliquer à nouveau ces règles correctement ; vous voulez que votre domaine les connaisse déjà et les applique.
la source
Widget
, la même règle s'applique partout. (Alors ne risquez pas de laisser quelqu'un l'ignorer!) Si la règle ne s'applique pas partout, ce n'est pas vraiment une règle à proposWidgets
et seulementWidgets
. . Repousser les règles aussi loin qu'elles (la ou les règles individuelles) peuvent aller; mais pas aussi loin que les "règles" peuvent aller ... J'ai l'impression de ne pas bien faire la distinction. Mais, il est censé y avoir une distinction.