User Auth in EventSourcing applications

Patrzę na tworzenie aplikacji z DDD+CQRS+EventSourcing, i mam pewien problem z wymyśleniem, jak zrobić user auth.

Użytkownicy są nieodłączną częścią mojej domeny, ponieważ są odpowiedzialni za klientów. Używam ASP.NET MVC 4, A ja chciałem po prostu skorzystać z SimpleMembership. Ponieważ logowanie i autoryzacja użytkowników jest operacją synchroniczną, w jaki sposób można to rozwiązać w docelowej spójnej architekturze?

Czy będę musiał włączyć własny system auth tam gdzie trzymam denormalizowane tabele auth po stronie odczytu? Jak sobie z tym poradzić? Czy w końcu będę przechowywać hashe haseł zarówno w moim magazynie zdarzeń, jak i w tabelach widoku?

Tyle pytań, jeśli ktoś może rzucić trochę światła, będę bardzo wdzięczny:)

Tldr; jak zrobić user Auth w EventSource-applications?

Author: tuxbear, 2013-03-26

3 answers

Nie każda" domena " lub komponent biznesowy musi używać DDD lub CQR. W większości przypadków informacje o użytkowniku są naprawdę brudne, więc zazwyczaj nie można do tego używać DDD. Inne domeny tak naprawdę nie zależą od rzeczywistego użytkownika. Zazwyczaj istnieje identyfikator korelacji (UserId), który jest współdzielony przez różne domeny.

Jeśli używasz wiadomości w systemie, jedną z opcji jest rejestracja i zarządzanie użytkownikami bez CQRS, a następnie wysłanie polecenia (RegisterUser { UserId }). Spowoduje to opublikowanie Zarejestrowanego Użytkownika zdarzenia. Inne domeny mogą słuchać tego wydarzenia, aby rozpocząć wszelkie przepływy pracy lub Ar, które są potrzebne.

 10
Author: Jonathan Matheus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-26 18:10:34

Dla naszej aplikacji MVC CQRS, początkowo zaczęliśmy przechowywać wszystkie informacje związane z użytkownikiem w domenie i, jak ktoś wspomniał, było RegisterUserCommand i UserRegisteredEvent. Po zapisaniu informacji o użytkowniku w domenie, zdarzenie to zostało opublikowane i odebrane po stronie odczytu, która również utworzyła użytkownika i wygenerowała wszystkie hasze haseł itp. Następnie wykonaliśmy uwierzytelnianie po stronie odczytu: kontroler wywołałby " uwierzytelnianie modelu odczytu serwis " do uwierzytelniania przeciw.

Później na końcu drogi, skończyło się całkowicie refaktoryzacji tego. Okazało się, że potrzebowaliśmy dostępu do informacji związanych z użytkownikiem, aby zbudować bezpieczeństwo autoryzacji naszych poleceń, co zrobiliśmy po stronie przetwarzania poleceń (nasza aplikacja jest rozproszoną aplikacją, która wysyła asynchroniczne polecenia 'fire and forget' do kolejki, z autonomicznym słuchaczem po drugiej stronie). Komponent bezpieczeństwa wymagał wtedy odniesienia do naszej domeny, aby przejść i uzyskać użytkownika profilu, co prowadziło do uciążliwych problemów związanych z nawiązywaniem

Zdecydowaliśmy się umieścić zabezpieczenia użytkowników w oddzielnej bazie danych, która uważaliśmy za bardziej centralny komponent, a nie należącą do domeny lub modelu read. Nadal utrzymujemy informacje o Profilu Użytkownika w domenie i odczytujemy modele (np. tytuł pracy, adres URL konta na Twitterze itp.), ale wszystkie kwestie związane z bezpieczeństwem, takie jak skróty haseł, są przechowywane w tej centralnej bazie danych. To jest wtedy dostępne z usługa, która jest dostępna zarówno dla MVC, jak i autoryzatora poleceń.

W rzeczywistości nie musieliśmy zmieniać niczego w interfejsie użytkownika dla tego refactor, ponieważ właśnie wywołaliśmy usługę, aby zarejestrować użytkowników z obsługi polecenia register user. Jeśli zamierzasz to zrobić w ten sposób, musisz być ostrożny, aby operacje związane z usługą użytkownika były idempotentne. To jest tak, że można dać komend możliwość ponownego wypróbowania bez skutków ubocznych, ponieważ aktualizujesz 2 Źródła informacje (ES i baza danych użytkowników).

Wreszcie, można oczywiście użyć dostawców członkostwa dla tego centralnego komponentu, ale mogą być pułapki z tym. Skończyło się na pisaniu własnych-to dość proste. Ten artykuł odsyła do tego , który jest dobrym przykładem tego, jak go wdrożyć.

 10
Author: jacderida,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-31 22:53:21

Powinieneś rozważyć utworzenie osobnych podmiotów, takich jak: gość (właśnie odwiedził Twoją stronę), użytkownik (zarejestrowany), Klient (kupił coś) itp. Spróbuj podzielić system w ten sposób, nawet jeśli spowoduje to trochę nadmiarowości danych. Miejsce na dysku nie jest problemem, ale możliwość samodzielnej modyfikacji różnych komponentów systemu jest zwykle bardzo krytyczna.

Ludzie tworzą denormalizowane tabele auth tylko w celu skalowania i tylko wtedy, gdy strona odczytu auth jest wydajnością wąskie gardło. Jeśli nie-zwykle 3. normalna forma jest droga.

W scenariuszu SimpleMembership wszystkie tabele utworzone przez SimpleMembership mogą być wyświetlane jako migawka agregatu "user". I tak, powieli niektóre dane w Twoim sklepie z wydarzeniami. Możesz mieć zdarzenia takie jak: UserCreated, UserUpdated, UserAssignedToRole, itp.

I nie daj się zwieść nazwie tego dostawcy członkostwa. To nie jest takie proste i zwykle ma wiele rzeczy, bez których można łatwo żyć (zależy od domena). Więc może przydałoby się coś takiego: https://gist.github.com/Kayli/fe73769f19fdff40c3a7

 0
Author: IlliakaillI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-27 00:57:04