Je travaille sur une petite application essayant de comprendre les principes de la conception pilotée par domaine. En cas de succès, cela pourrait être un pilote pour un projet plus vaste. J'essaie de suivre le livre "Implémentation d'une conception pilotée par le domaine" (par Vaughn Vernon) et j'essaie de mettre en œuvre un forum de discussion simple et similaire. J'ai également vérifié les échantillons IDDD sur github. J'ai quelques difficultés à adopter l'identité et l'accès à mon dossier. Permettez-moi de donner quelques informations générales:
- J'espère (je l'espère) comprendre le raisonnement derrière la séparation de la logique des utilisateurs et des autorisations: il s'agit d'un domaine de prise en charge et d'un contexte borné différent.
- Dans le domaine principal, il n'y a pas d'utilisateurs, juste des auteurs, des modérateurs, etc.
Les opérations de domaine sont appelées avec un rôle associé comme paramètre: par exemple:
ModeratePost( ..., moderator);
La méthode de l'objet de domaine vérifie si l'instance Moderator donnée n'est pas nulle (l'instance Moderator sera nulle si l'utilisateur demandé dans le contexte Identity and Access n'a pas le rôle Moderator).
Dans un cas, il effectue une vérification supplémentaire avant de modifier une publication:
if (forum.IsModeratedby(moderator))
Mes questions sont:
Dans ce dernier cas, les problèmes de sécurité ne sont-ils pas à nouveau intégrés au domaine principal? Auparavant, les livres stipulaient "avec qui peut publier un sujet, ou dans quelles conditions cela est autorisé. Un forum a juste besoin de savoir qu'un auteur le fait en ce moment".
L'implémentation basée sur les rôles dans le livre est assez simple: lorsqu'un modérateur est le domaine principal essaie de convertir l'ID utilisateur actuel en une instance de modérateur ou en un auteur lorsqu'il en a besoin. Le service répondra avec l'instance appropriée ou une valeur nulle si l'utilisateur n'a pas le rôle requis. Cependant, je ne vois pas comment l'adapter à un modèle de sécurité plus complexe; notre projet actuel pour lequel je pilote a un modèle assez complexe avec des groupes, des ACL, etc.
Même avec des règles qui ne sont pas très complexes, comme: "Un article ne doit être édité que par son propriétaire ou un éditeur", cette approche semble s'effondrer, ou du moins je ne vois pas la bonne façon de l'implémenter.
En demandant le contexte d'identité et d'accès pour une instance OwnerOrEditor ne me semble pas correct, et je me retrouverais avec de plus en plus de classes liées à la sécurité dans le domaine principal. De plus, je devrais passer non seulement l'ID utilisateur, mais l'identifiant de la ressource protégée (l'identifiant de la publication, le forum, etc.) au contexte de sécurité, qui ne devrait probablement pas se soucier de ces choses (est-ce correct? )
En tirant les autorisations sur le domaine principal et en les vérifiant dans les méthodes des objets de domaine ou dans les services, je me retrouvais à la case départ: mélanger les problèmes de sécurité avec le domaine.
J'ai lu quelque part (et j'ai tendance à être d'accord avec lui) que ces choses liées aux autorisations ne devraient pas faire partie du domaine principal, à moins que la sécurité et les autorisations ne soient le domaine principal lui-même. Une règle simple comme celle donnée ci-dessus justifie-t-elle d'intégrer la sécurité dans le domaine principal?
la source
HasPermissionToEdit(userId, resourceId)
mais je ne me sens pas bien de contaminer la logique du domaine avec ces appels. Je devrais probablement vérifier ces derniers dans les méthodes de service d'application, avant d'invoquer la logique de domaine?UserService @AccessControlList[inf3rno]
dans la réponse à laquelle j'étais liée.Réponses:
Il est parfois difficile de faire la distinction entre les règles de contrôle d'accès réelles et les invariants de domaine limitant le contrôle d'accès.
En particulier, les règles qui dépendent de données disponibles uniquement très loin dans le cours d'un morceau particulier de logique de domaine peuvent ne pas être facilement extractibles hors du domaine. Habituellement, le contrôle d'accès est appelé avant ou après une opération de domaine, mais pas pendant.
L'
assert (forum.IsModeratedBy(moderator))
exemple de Vaughn Vernon aurait probablement dû être en dehors du domaine, mais ce n'est pas toujours faisable.S'il y a un Security BC et que vous voulez qu'il gère cette logique, il n'a pas besoin de savoir ce qu'est un Forum en détail mais:
la source
moderator = securityService.GetModerator(userId, forumId)
4. La logique du domaine sera implémentée dans ces objets comme dans moderator.EditPost () 5. Les méthodes comme EditPost ne connaîtront rien des concepts de sécurité, il n'y aura pas de vérifications supplémentaires làL'authentification et l'autorisation sont un mauvais exemple pour DDD.
Aucune de ces choses ne fait partie d'un domaine à moins que votre entreprise ne crée des produits de sécurité.
L'exigence commerciale ou de domaine est, ou devrait être, "J'ai besoin d'une authentification basée sur les rôles"
Vous vérifiez ensuite le rôle avant d'appeler une fonction de domaine.
Lorsque vous avez des exigences complexes telles que «Je peux modifier mes propres publications mais pas les autres», assurez-vous que votre domaine sépare la fonction de modification dans
EditOwnPost()
etEditOthersPost()
que vous disposez d'une fonction simple pour le mappage des rôlesVous pouvez également séparer la fonctionnalité en objets de domaine, tels que
Poster.EditPost()
etModerator.EditPost()
il s'agit d'une approche plus POO, bien que votre choix puisse dépendre si votre méthode se trouve dans un service de domaine ou un objet de domaine.Quelle que soit la façon dont vous choisissez de séparer le code, le mappage de rôle se produira en dehors du domaine. donc par exemple si vous avez un contrôleur webapi:
Comme vous pouvez le voir, bien que le mappage des rôles soit effectué sur la couche d'hébergement, la logique complexe de ce qui constitue la modification de votre propre publication ou d'une autre fait partie du domaine.
Le domaine reconnaît la différence des actions, mais l'exigence de sécurité est simplement que "la fonctionnalité peut être limitée par les rôles" .
C'est peut-être plus clair avec la séparation des objets de domaine, mais vous vérifiez essentiellement la méthode qui construit l'objet au lieu de la méthode qui appelle la méthode de service. Votre exigence, si vous voulez toujours l'exprimer dans le cadre du domaine deviendrait «seuls les modérateurs peuvent construire l'objet modérateur»
la source