Nie zdecydowałbym się wypowiedzieć oryginalnego komentarza w sposób, w jaki został sformułowany, ale identyfikuje on potencjalnie uzasadniony problem.
W szczególności obawy, które uzasadniają separację, to uwierzytelnianie vs. autoryzacja .
Uwierzytelnianie odnosi się do procesu logowania i uzyskiwania tożsamości. W ten sposób systemy wiedzą, kim jesteś , i są wykorzystywane do personalizacji, własności obiektu itp.
Autoryzacja odnosi się do tego, co wolno ci robić , a to (ogólnie) nie zależy od tego, kim jesteś . Zamiast tego zależy to od niektórych zasad bezpieczeństwa, takich jak role lub uprawnienia, które nie dbają o takie rzeczy, jak imię i nazwisko lub adres e-mail.
Ci dwaj mogą zmieniać się ortogonalnie. Na przykład możesz zmienić model uwierzytelniania, dodając dostawców OpenID / OpenAuth. Możesz także zmienić politykę bezpieczeństwa, dodając nową rolę lub zmieniając RBAC na ABAC.
Jeśli wszystko to zostanie ujęte w jedną klasę lub abstrakcję, wówczas kod bezpieczeństwa, który jest jednym z najważniejszych narzędzi ograniczania ryzyka , staje się, jak na ironię, wysokim ryzykiem.
Pracowałem z systemami, w których uwierzytelnianie i autoryzacja były zbyt ściśle powiązane. W jednym systemie istniały dwie równoległe bazy danych użytkowników, każda dla jednego rodzaju „roli”. Osoba lub zespół, który ją zaprojektował, najwyraźniej nigdy nie uważał, że pojedynczy użytkownik fizyczny może pełnić obie role lub że mogą istnieć pewne działania, które były wspólne dla wielu ról lub że mogą występować problemy z kolizjami ID użytkownika. Jest to wprawdzie skrajny przykład, ale praca z nim była / jest niezwykle bolesna.
Microsoft i Sun / Oracle (Java) określają agregację informacji o uwierzytelnianiu i autoryzacji jako Principal Security . Nie jest idealny, ale działa dość dobrze. W .NET, na przykład, masz IPrincipal
, który obudowujeIIdentity
- dawna będąc polityka (autoryzacja) przedmiot, a drugi jest tożsamość (uwierzytelnianie). Można rozsądnie zakwestionować decyzję o umieszczeniu jednego w drugim, ale ważne jest to, że większość pisanego kodu będzie dotyczyła tylko jednej z abstrakcji, co oznacza, że łatwo go przetestować i zmienić.
Nie ma nic złego w User.IsAdmin
polu ... chyba że jest też User.Name
pole. Oznaczałoby to, że koncepcja „użytkownika” nie jest właściwie zdefiniowana i jest to niestety bardzo częsty błąd programistów, którzy są nieco mokrzy za uszami, jeśli chodzi o bezpieczeństwo. Zazwyczaj jedyną rzeczą, która powinna być współdzielona przez tożsamość i zasady, jest identyfikator użytkownika, który nieprzypadkowo jest dokładnie taki, jak jest implementowany zarówno w modelach bezpieczeństwa Windows, jak i * nix.
Całkowicie dopuszczalne jest tworzenie obiektów opakowujących, które zawierają zarówno tożsamość, jak i zasady. Ułatwi to na przykład utworzenie ekranu deski rozdzielczej, na którym oprócz różnych widżetów lub łączy, do których bieżący użytkownik ma dostęp, należy wyświetlić komunikat „cześć”. Tak długo, jak to opakowanie po prostu otacza informacje dotyczące tożsamości i zasad i nie rości sobie prawa do ich posiadania. Innymi słowy, o ile nie jest prezentowany jako zagregowany katalog główny .
Uproszczony model bezpieczeństwa zawsze wydaje się dobrym pomysłem przy pierwszym projektowaniu nowej aplikacji, ze względu na YAGNI i tak dalej, ale prawie zawsze wraca, by cię ugryźć później, ponieważ, niespodzianka, nowe funkcje są dodawane!
Jeśli więc wiesz, co jest dla Ciebie najlepsze, informacje dotyczące uwierzytelniania i autoryzacji będą oddzielone. Nawet jeśli „autoryzacja” jest teraz tak prosta jak flaga „IsAdmin”, nadal będziesz lepiej, jeśli nie jest częścią tej samej klasy lub tabeli co informacje uwierzytelniające, więc jeśli i kiedy twoja polityka bezpieczeństwa musi zmiana, nie musisz wykonywać operacji rekonstrukcyjnych w systemach uwierzytelniania, które już działają dobrze.