Estoy trabajando en una pequeña aplicación que intenta comprender los principios del diseño basado en dominios. Si tiene éxito, esto podría ser un piloto para un proyecto más grande. Estoy tratando de seguir el libro "Implementando el diseño impulsado por el dominio" (por Vaughn Vernon) e intentando implementar un foro de discusión simple y similar. También he revisado las muestras IDDD en github. Tengo algunas dificultades para adoptar la identidad y el acceso a mi caso. Déjame darte información de fondo:
- (Con suerte) entiendo el razonamiento detrás de la separación de los usuarios y la lógica de permisos: es un dominio de soporte, y es un contexto limitado diferente.
- En el dominio central, no hay usuarios, solo Autores, Moderadores, etc. Estos se crean al llegar al contexto de Identidad y Acceso utilizando un servicio y luego traduciendo los objetos de Usuario recibidos a Moderador.
Las operaciones de dominio se llaman con un rol relacionado como parámetro: por ejemplo:
ModeratePost( ..., moderator);
El método del objeto de dominio verifica si la instancia de Moderador dada no es nula (la instancia de Moderador será nula si el usuario que se le preguntó desde el contexto de Identidad y Acceso no tiene la función de Moderador).
En un caso, realiza una comprobación adicional antes de modificar una publicación:
if (forum.IsModeratedby(moderator))
Mis preguntas son:
En el último caso, ¿no se mezclan nuevamente las preocupaciones de seguridad en el dominio principal? Anteriormente, los libros decían "con quién puede publicar un tema, o bajo qué condiciones está permitido. Un foro solo necesita saber que un autor está haciendo eso ahora".
La implementación basada en roles en el libro es bastante sencilla: cuando un Moderador es el dominio principal, trata de convertir el ID de usuario actual en una instancia de Moderador o en un Autor cuando lo necesita. El servicio responderá con la instancia apropiada o un valor nulo si el usuario no tiene el rol requerido. Sin embargo, no puedo ver cómo podría adaptar esto a un modelo de seguridad más complejo; nuestro proyecto actual para el que estoy probando tiene un modelo bastante complejo con grupos, ACL, etc.
Incluso con reglas que no son muy complejas, como: "Una publicación debe ser editada solo por su propietario o un editor", este enfoque parece fallar, o al menos no veo la forma correcta de implementarlo.
Al preguntar el contexto de Identidad y Acceso para una instancia de OwnerOrEditor no se siente bien, y terminaría con más y más clases relacionadas con la seguridad en el dominio central. Además, necesitaría pasar no solo el ID de usuario, sino también el identificador del recurso protegido (la identificación de la publicación, el foro, etc.) al contexto de seguridad, que probablemente no debería importarles estas cosas (¿es correcto? )
Al extraer los permisos para el dominio central y verificarlos en los métodos de los objetos de dominio o en los servicios, terminaría en el primer lugar: mezclar las preocupaciones de seguridad con el dominio.
He leído en alguna parte (y tiendo a estar de acuerdo) que estas cosas relacionadas con los permisos no deberían ser parte del dominio central, a menos que la seguridad y los permisos sean el dominio central en sí. ¿Una regla simple como la dada anteriormente justifica que la seguridad sea parte del núcleo del dominio?
fuente
HasPermissionToEdit(userId, resourceId)
pero no me parece correcto contaminar la lógica del dominio con estas llamadas. ¿Probablemente debería verificar esto en los métodos de servicio de la aplicación, antes de invocar la lógica de dominio?UserService @AccessControlList[inf3rno]
en la respuesta a la que me vinculé.Respuestas:
A veces es difícil distinguir entre las reglas de control de acceso real y los invariantes de dominio que bordean el control de acceso.
Especialmente, las reglas que dependen de datos solo disponibles en el curso de una determinada pieza de lógica de dominio podrían no ser fácilmente extraíbles del dominio. Por lo general, se llama a Control de acceso antes o después de realizar una operación de dominio, pero no durante.
El
assert (forum.IsModeratedBy(moderator))
ejemplo de Vaughn Vernon probablemente debería haber estado fuera del Dominio, pero no siempre es factible.Si hay un BC de seguridad y desea que maneje esa lógica, no tiene que saber qué es un foro en detalle, sino:
fuente
moderator = securityService.GetModerator(userId, forumId)
4. La lógica de dominio se implementará en estos objetos como en moderator.EditPost () 5. Los métodos como EditPost no sabrán nada sobre conceptos de seguridad, no habrá verificaciones adicionales allíLa autenticación y autorización es un mal ejemplo para DDD.
Ninguna de estas cosas es parte de un Dominio a menos que su empresa cree productos de seguridad.
El requisito comercial o de dominio es, o debería ser, "Requiero autenticación basada en roles"
Luego verifica el rol antes de llamar a una función de dominio.
Cuando tenga requisitos complejos como 'Puedo editar mis propias publicaciones pero no otras', asegúrese de que su dominio separe la función de edición
EditOwnPost()
y deEditOthersPost()
que tenga una función simple para mapear rolesTambién puede separar la funcionalidad en Objetos de dominio, por ejemplo,
Poster.EditPost()
yModerator.EditPost()
este es un enfoque más orientado a objetos, aunque su elección puede depender de si su método está en un Servicio de dominio o en un Objeto de dominio.Sin embargo, si elige separar el código, la asignación de roles se realizará fuera del dominio. así, por ejemplo, si tiene un controlador webapi:
Como puede ver, aunque el mapeo de roles se realiza en la capa de alojamiento, la lógica compleja de lo que constituye editar su propia publicación o la de otros es parte del dominio.
El dominio reconoce la diferencia de las acciones, pero el requisito de seguridad es simplemente que "la funcionalidad puede estar limitada por roles" .
Esto es quizás más claro con la separación de objetos de dominio, pero esencialmente está verificando el método que construye el objeto en lugar del método que llama al método de servicio. Su requisito, si aún desea expresarlo como parte del dominio, se convertiría en 'solo los moderadores pueden construir el objeto moderador'
fuente