Pracuję nad małą aplikacją, próbując zrozumieć zasady projektowania opartego na domenie. Jeśli się powiedzie, może to być projekt pilotażowy dla większego projektu. Staram się podążać za książką „Implementing Domain-Driven Design” (autor: Vaughn Vernon) i próbuję wdrożyć podobne, proste forum dyskusyjne. Sprawdziłem również próbki IDDD na github. Mam pewne trudności z przyjęciem Tożsamości i dostępu do mojej sprawy. Pozwól, że podam kilka podstawowych informacji:
- (Mam nadzieję) rozumiem uzasadnienie oddzielenia logiki użytkowników i uprawnień: jest to domena wspierająca i inny kontekst ograniczony.
- W domenie podstawowej nie ma użytkowników, tylko autorzy, moderatorzy itp. Są oni tworzeni, docierając do kontekstu tożsamości i dostępu za pomocą usługi, a następnie tłumacząc otrzymane obiekty użytkownika na i moderatora.
Operacje w domenie są wywoływane z powiązaną rolą jako parametrem: np .:
ModeratePost( ..., moderator);
Metoda obiektu domeny sprawdza, czy dana instancja Moderator nie ma wartości Null (instancja Moderator będzie pusta, jeśli użytkownik zapytany z kontekstu Tożsamość i Dostęp nie ma roli Moderator).
W jednym przypadku dokonuje dodatkowej kontroli przed zmianą posta:
if (forum.IsModeratedby(moderator))
Moje pytania to:
W tym drugim przypadku obawy dotyczące bezpieczeństwa nie są ponownie mieszane w domenie podstawowej? Wcześniej książki stwierdzają „z kim można opublikować temat lub na jakich warunkach jest to dozwolone. Forum musi tylko wiedzieć, że autor robi to teraz”.
Implementacja oparta na rolach w książce jest dość prosta: gdy Moderator jest domeną podstawową, próbuje przekonwertować bieżącego ID użytkownika na instancję Moderatora lub Autor, gdy tego potrzebuje. Usługa odpowie odpowiednią instancją lub wartością null, jeśli użytkownik nie ma wymaganej roli. Nie widzę jednak, jak mogę dostosować to do bardziej złożonego modelu bezpieczeństwa; nasz obecny projekt, dla którego pilotuję, ma dość złożony model z grupami, listami kontroli dostępu itp.
Nawet w przypadku reguł, które nie są zbyt skomplikowane, takich jak: „Post powinien być edytowany tylko przez jego właściciela lub redaktora”, to podejście wydaje się załamać, a przynajmniej nie widzę właściwego sposobu na jego wdrożenie.
Pytanie o kontekst Tożsamość i dostęp do instancji OwnerOrEditor nie wydaje się właściwe, a ja kończyłbym coraz większą liczbą klas związanych z bezpieczeństwem w domenie podstawowej. Ponadto musiałbym przekazać nie tylko identyfikator użytkownika, ale identyfikator chronionego zasobu (identyfikator wpisu, forum itp.) Do kontekstu bezpieczeństwa, który prawdopodobnie nie powinien dbać o te rzeczy (czy to prawda? )
Wyciągając uprawnienia do podstawowej domeny i sprawdzając je w metodach obiektów domeny lub w usługach, skończyłem na pierwszym: mieszanie problemów związanych z bezpieczeństwem z domeną.
Czytałem gdzieś (i zgadzam się z tym), że te rzeczy związane z uprawnieniami nie powinny być częścią domeny podstawowej, chyba że bezpieczeństwo i uprawnienia są samą domeną rdzeniową. Czy prosta reguła, taka jak podana powyżej, uzasadnia uczynienie bezpieczeństwa częścią podstawowej domeny?
źródło
HasPermissionToEdit(userId, resourceId)
ale nie czuję się dobrze, aby zanieczyszczać logikę domeny tymi wywołaniami. Prawdopodobnie powinienem je sprawdzić w metodach obsługi aplikacji przed wywołaniem logiki domeny?UserService @AccessControlList[inf3rno]
w odpowiedzi, z którą się łączyłem.Odpowiedzi:
Czasami trudno jest odróżnić rzeczywiste reguły kontroli dostępu od niezmienników domeny graniczących z kontrolą dostępu.
W szczególności reguły, które zależą od danych dostępnych tylko w dalszej części logiki domeny, mogą nie być łatwe do wydobycia z domeny. Zwykle kontrola dostępu jest wywoływana przed lub po wykonaniu operacji domeny, ale nie w trakcie.
assert (forum.IsModeratedBy(moderator))
Przykład Vaughna Vernona prawdopodobnie powinien być poza domeną, ale nie zawsze jest to wykonalne.Jeśli istnieje Security BC i chcesz, aby obsługiwał tę logikę, nie musi wiedzieć, czym jest forum, ale:
źródło
moderator = securityService.GetModerator(userId, forumId)
4. Logika domeny zostanie zaimplementowana w tych obiektach, jak w moderator.EditPost () 5. Metody takie jak EditPost nie będą wiedzieć o koncepcjach bezpieczeństwa, nie będzie żadnych dodatkowych kontroli tamUwierzytelnianie i autoryzacja to zły przykład dla DDD.
Żadna z tych rzeczy nie jest częścią Domeny, chyba że Twoja firma tworzy produkty bezpieczeństwa.
Wymaganiem biznesowym lub domeny jest lub powinno być „Wymagam uwierzytelnienia opartego na rolach”
Następnie sprawdź rolę przed wywołaniem funkcji domeny.
Jeśli masz złożone wymagania, takie jak „Mogę edytować własne posty, ale nie inne”, upewnij się, że Twoja domena dzieli funkcję edycji na,
EditOwnPost()
iEditOthersPost()
że masz prostą funkcję do mapowania rólMożesz także podzielić funkcjonalność na Obiekty Domeny, takie jak
Poster.EditPost()
iModerator.EditPost()
jest to bardziej podejście OOP, chociaż twój wybór może zależeć od tego, czy twoja metoda jest w Usłudze Domeny, czy Obiektu Domeny.Bez względu na to, czy zdecydujesz się oddzielić kod, mapowanie ról nastąpi poza domeną. na przykład jeśli masz kontroler webapi:
Jak widać, chociaż rola mapowanie odbywa się na warstwie hosting, kompleks logika tego, co stanowi edycji własnego lub innych post jest częścią domeny.
Domena rozpoznaje różnicę działań, ale wymóg bezpieczeństwa polega po prostu na tym, że „funkcjonalność może być ograniczona rolami” .
Być może jest to wyraźniejsze w przypadku separacji obiektów domeny, ale zasadniczo sprawdzasz metodę konstruującą obiekt zamiast metody wywołującej metodę usługi. Twój wymóg, jeśli nadal chcesz wyrazić to jako część domeny, stałby się „tylko moderatorzy mogą zbudować obiekt moderatora”
źródło