2012-03-11 14 views
12

Chciałbym usłyszeć kilka myśli na temat najlepszego sposobu optymalizacji naszego schematu, aby osiągnąć następujące.Najlepszy sposób zarządzania uprawnieniami użytkownika/obiektu grupowego za pomocą Symfony2

Mamy liczbę obiektów/db wpisy (imprezy, lokali itp), z których niektóre mają dzieci obiektów (czyli zastosować te same uprawnienia - zdjęcia, Metas, etc)

użytkownicy mogą należeć do grup tak rodzica Obiekty takie jak wydarzenia, miejsca mogą być edytowalne/widoczne dla wszystkich, tylko dla grupy, tylko dla jednego użytkownika.

Obecnie mamy tabelę użytkowników, grup użytkowników i grup do zarządzania użytkownikami i grupami.

Każdy obiekt nadrzędny, taki jak miejsca, jako kolumna dla id_użytkownika i identyfikator_grupy.

Działa dobrze (w Symfony 1.4), ale jest brudny - każde zapytanie o cokolwiek musi być złożone, aby uzyskać możliwe grupy itp. Chcielibyśmy znaleźć prostszy sposób.

Byłem bardzo podekscytowany komponentem ACL Sf2, ale ciągle mi powtarzano, że nie powinienem używać go do znajdowania obiektów, którymi może zarządzać użytkownik - raczej powinienem użyć ACL, aby dowiedzieć się, czy użytkownik jest dozwolony zarządzać własnymi przedmiotami (nie wydaje się bardzo przydatny, ale cokolwiek).

Wszystkie alternatywne próby, które udało mi się znaleźć, mówią, że należy wyciągnąć wszystkie obiekty z db, a następnie filtrować według ACL - to urocze dla mamy i strony pop - nie stanie się z milionem obiektów.

Więc ... Chciałbym usłyszeć pomysły na to, w jaki sposób możemy to zrobić - jesteśmy również otwarci na pozostawienie symfony dla czegoś, co ma skalowalne rozwiązanie ACL, ale do tej pory nie znaleźliśmy niczego (php lub ruby), więc otwarte na to, chociaż chcielibyśmy nadal używać Sf. Zauważ, że zamierzamy używać MongoDB w przypadku, gdy ma to znaczenie.

Odpowiedz

11

Z tego, co rozumiem, lista ACL jest używana w celu uzyskania dostępu do określonego obiektu dla konkretnej osoby w przypadku specjalnych scenariuszy. To, co opisujesz, jest bardziej ogólne, ale po prostu odbiega od tego, co Symfony2 określa dla bezpieczeństwa (ta osoba ma rolę "administratora", ale tylko dla obiektów zawartych w określonej grupie).

Listy ACL nie powinny być używane do przechowywania wielu rzeczy, ponieważ sprawdzenie może stać się drogie, jeśli stanie się zbyt duże. Tak więc domyślnie umieszczamy tutaj kilka rzeczy, gdy dodawani są nowi użytkownicy, lub nawet gdy dodawane są nowe obiekty w grupie (jeśli używasz listy ACL, musisz dodać wpis do każdej osoby w grupie za każdym razem, gdy utworzysz nowy obiekt), po pewnym czasie będzie obciążał wydajność ...

Obecnie badam możliwość użycia Symfony2 do aplikacji internetowej, ale ja też uderzam w ścianę z tym zabezpieczeniem, tak jak mamy podobna potrzeba. Nie jestem ekspertem w Symfony2, ale z tego, co wyglądało by, może masz kilka opcji:

  1. Tworzenie wyborca ​​do obsługi tego. Wyborcy umożliwiają sprawdzenie tokenów autoryzacji i zwracają informację, czy dostęp jest przyznawany czy odmawiany w zależności od sposobu ich przetwarzania. Możesz więc stworzyć niestandardowego Votera, który sprawdza grupę użytkownika i próbuje dopasować ją do grupy, której obiekt jest podrzędny. Jeśli tak, zwróć ACCESS_GRANTED, w przeciwnym razie ACCESS_DENIED lub ACCESS_ABSTAIN, jeśli Voter nie jest ważny dla bieżącego czeku. EDYCJA: Oto link do książki kucharskiej Symfony2 dla głosujących:

  2. Może również chcieć zbadać interfejs SecurityContext. Zapewnia to metodę "isGranted()", która zajmuje się określaniem dostępu do obiektów.Jeśli wyborcy nie są wystarczająco prosto, może trzeba pójść drogą tworząc nową klasę SecurityContext; Myślę, że byłoby to jednak nieco bardziej zaangażowane.

Tak jak powiedziałem, nie jestem profesjonalistą i nie mam rozwiązania; to tylko niektóre kierunki, które badam, aby spróbować rozwiązać (jak mi się wydaje) podobny problem. Mam nadzieję, że to trochę pomaga.

1

Minęło trochę czasu odkąd pisał mój oryginalny odpowiedź na to pytanie, ale chciał śledzić z innego rozwiązania, jeden który używamy obecnie.

Podczas gdy Symfony daje warstwę bezpieczeństwa/ACL do użycia, nie musisz mieć, aby go użyć, lub przynajmniej w pełni.

Na niemal każdym momencie w kodzie, można rzucić Symfony\Component\Security\Core\Exception\AccessDeniedException i warstwę zabezpieczeń będzie „Kick in” i obsługiwać je za ciebie, jak przekierowanie użytkownika do strony logowania, itp

Some tej interakcji może wymagać nieco bardziej zaawansowanej konfiguracji firewalla, aby działała dokładnie tak, jak tego chcesz.

Krótko mówiąc, podczas Symfony zapewnia wspaniałe mechanizmy i funkcje, które pomogą zbudować ACL, nie trzeba pracować, aby dopasować swoje dane i procesy w co mają zdefiniowane.

nasz system jako przykład mamy Konta, role, i grupy w naszym systemie (wraz z uprawnieniami). Podzielimy również sekcje danych na działy. Podczas gdy użytkownicy mogą mieć role i uprawnienia na poziomie globalnym, mogą także mieć dostęp do działu. Taka konfiguracja wykonane za pomocą wbudowanego w Symfony ACL funkcje i narzędzia kontroli dostępu niemal bezużyteczny (nie oznacza ich narzędzia są bezużyteczne, są świetne w rzeczywistości, po prostu nie pasuje do naszego przypadek użycia). Zbudowaliśmy więc własną usługę (która korzysta z precyzyjnie dostosowanych zapytań), w której przekazujemy odpowiednie dane dotyczące czeku i generuje odpowiednią liczbę Symfony\Component\Security\Core\Exception\AccessDeniedException, gdy czek nie powiedzie się.