Quelle est la place de l'autorisation dans une architecture en couches?

24

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.

à M
la source
1
Le statut 403 est incorrect pour les problèmes d'autorisation. Utilisez 401.
gnasher729
@ gnasher729 Je pense que c'est à l'envers. 401 signifie que l'authentification a échoué ou n'est pas fournie, 403 signifie que vous n'avez pas de droits d'accès: stackoverflow.com/questions/3297048/…
JimmyJames
@JimmyJames, il existe une autre école de pensée selon laquelle vous ne devriez utiliser qu'un seul d'entre eux pour tous les échecs d'authentification et d'autorisation, car il ne permet pas aux outils automatisés d'inférer aussi facilement la logique métier. Il y a une certaine latitude.
Berin Loritsch
1
@BerinLoritsch Désolé, dites-vous que l'idée est de rendre plus difficile à comprendre s'il s'agit d'un problème d'authentification ou d'autorisation? La RFC semble assez claire mais indique que vous pouvez utiliser 404 au lieu de 403 si vous ne souhaitez pas exposer trop d'informations. Y a-t-il une référence que vous pouvez fournir pour l'argument pour utiliser un 401 au lieu de 403?
JimmyJames
@JimmyJames, oui. Ce processus de réflexion provient de professionnels de la sécurité, pas de développeurs. Et j'ai également vu votre recommandation de 404 pour masquer complètement les informations pour cacher que la ressource existe même.
Berin Loritsch

Réponses:

9

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.

James Anderson
la source
7

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».

ialekseev
la source
7

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.

svidgen
la source
@Shoe Si je comprends votre préoccupation - c'est en quelque sorte le point. Si seul un "administrateur" a l'autorisation, selon les règles métier, de créer un 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 à propos Widgetset seulement Widgets . . 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.
svidgen
D'après mon expérience, les règles d'autorisation font souvent partie des règles commerciales. En tant que tel, "aussi loin que possible" est souvent ma couche de domaine. Mais, je soupçonne que l'endroit où vos règles «devraient» tomber n'est qu'une conséquence de votre domaine, de la nature des règles et de la façon dont l'entreprise en parle.
svidgen