Gdzie autoryzacja pasuje do architektury warstwowej?

24

Zazwyczaj decyzje dotyczące autoryzacji umieszczam w moich kontrolerach po stronie serwera. To były ostatnio punkty końcowe RESTful, ale myślę, że to samo dotyczy architektur typu MVC. Dla argumentu załóżmy, że jest to autoryzacja oparta na rolach. Metoda chroniona zostanie opatrzona adnotacjami lub sprawdzi i zwróci 403 w razie potrzeby.

Teraz, biorąc pod uwagę, że autoryzacja jest w rzeczywistości regułą biznesową - na przykład „tylko administratorzy mogą wymienić X”, myślę, że powinni zostać zepchnięci na dół. Gdy kontroler prosi warstwę biznesową o wykonanie operacji, warstwa usługowa lub biznesowa informuje kontrolera, że ​​nie jest autoryzowana.

Czy to rozsądne podejście? Czy są to wady?

Nienawidzę posiadania usługi AuthorisationService, która zasadniczo zawiera kilka statycznych, kodowanych reguł proceduralnych, aby to zrobić, ale być może ma sens utrzymanie całej logiki dostępu w jednym miejscu. Czy to kwestia przekrojowa, którą należy oddzielić?

Pytam więc, czy ktoś to zrobił i jak udało mu się to osiągnąć w czysty sposób, czy też czy są jakieś dobre zasoby, które mógłbym przeczytać. Używam Java Fwiw, ale jest to pytanie agnostyczne języka.

Sprawdziłem pokrewne pytania tutaj i są bardzo cienkie na ziemi i odpowiedzi. Na przykład: Sprawdzanie poprawności i autoryzacja w modelach domen i przenoszenie jej przez warstwę usług do MVC

Czytam wiosenne dokumenty bezpieczeństwa, które stanowią dobry argument za tym, że jest to problem przekrojowy, ale martwię się, że to tylko „wiosenna droga” i chciałbym szerszych perspektyw. Powiązuje również twoją aplikację z konkretną strukturą.

Tomek
źródło
1
Stan 403 jest nieprawidłowy w przypadku problemów z autoryzacją. Użyj 401.
gnasher729,
@ gnasher729 Myślę, że to wstecz. 401 oznacza, że ​​uwierzytelnienie nie powiodło się lub nie zostało dostarczone, 403 oznacza, że ​​nie masz praw dostępu: stackoverflow.com/questions/3297048/…
JimmyJames
@JimmyJames, istnieje inna szkoła myślenia, że ​​powinieneś używać tylko jednego z nich do wszystkich niepowodzeń uwierzytelniania i autoryzacji, ponieważ nie pozwala to automatycznym narzędziom na łatwe wnioskowanie o logice biznesowej. Jest trochę swobody.
Berin Loritsch
1
@BerinLoritsch Przepraszamy, czy twierdzisz, że chodzi o utrudnienie zrozumienia, czy jest to problem z uwierzytelnieniem lub autoryzacją? RFC wydaje się dość jasne, ale stwierdza, że ​​możesz użyć 404 zamiast 403, jeśli nie chcesz ujawniać zbyt wielu informacji. Czy istnieje odniesienie, które można podać dla argumentu używania 401 zamiast 403?
JimmyJames
@JimmyJames, Tak. Ten proces myślowy pochodzi od specjalistów od bezpieczeństwa, a nie od programistów. Widziałem również twoją rekomendację 404, aby całkowicie ukryć informacje, aby ukryć, że zasób w ogóle istnieje.
Berin Loritsch

Odpowiedzi:

9

Dobrą praktyką jest ujawnianie tylko opcji, do których użytkownik jest upoważniony.

Wymusza to, aby zezwolenie było przekrojowe. „Widok” musi wiedzieć, co użytkownik może zrobić, zanim będzie mógł budować opcje i menu do wyświetlania.

Zaplecze nie powinno ufać frontonowi w podejmowaniu decyzji dotyczących bezpieczeństwa, dlatego musi sprawdzić samą autoryzację.

Mogą istnieć reguły biznesowe, które wpływają na autoryzację w zależności od danych, np. „Tylko użytkownicy z saldem powyżej 5000 $ mogą wykonać przelew walutowy” lub „Tylko użytkownicy z siedziby głównej mogą przeglądać te konta”. Dlatego w logice biznesowej wymagana jest pewna logika autoryzacji.

Należy również rozważyć uprawnienia techniczne - kto może przeglądać dzienniki, kto może tworzyć kopie zapasowe / przywracać bazę danych itp.

Tak więc ostatecznie każdy komponent może mieć określone wymagania bezpieczeństwa i / lub autoryzacji, w praktyce prawie niemożliwe jest zawinięcie go w osobną „warstwę autoryzacji”.

James Anderson
źródło
7

Myślę, że absolutnie rozsądne jest wprowadzenie autoryzacji w warstwie usług. Musisz chronić swoją usługę przed wykonywaniem nieautoryzowanych działań (szczególnie modyfikacji danych). Twoja warstwa usługi może znajdować się w jednej bibliotece i być używana przez różne warstwy prezentacji (możesz mieć różne aplikacje interfejsu użytkownika korzystające z tej samej warstwy usługi). I nie można polegać na tym, że określone warstwy prezentacji wykonują niezbędną weryfikację. Jest to szczególnie ważne, jeśli później zdecydujesz się przenieść warstwę usługi do osobnego procesu (np. Zgodnie z podejściem SOA).

Teraz o tym, jak to osiągnąć w „czysty sposób”. Nie podoba mi się pomysł zaśmiecania logiki biznesowej za pomocą kontroli autoryzacji, więc może pomóc konkretna implementacja podejścia do programowania aspektowego: może to być dekorowanie metod usług specjalnymi atrybutami lub używanie dynamicznych serwerów proxy z przechwytywaniem.

I, co ważne, muszę przyznać, że w bardzo prostych projektach możesz żyć bez oddzielnych walidacji, aby uprościć swoje życie. Ale ważne jest, aby nie przegapić momentu, w którym „prosty projekt” stał się „złożonym projektem”.

ialekseev
źródło
7

Lubię przesuwać kontrole autoryzacji tak nisko, jak to możliwe! (Ale nie dalej!)

Nadal masz swobodę pisania automatycznych testów autoryzacyjnych dla warstw „powyżej” tego. Niektóre reguły mogą mieć zastosowanie lub mieć sens tylko w wyższych warstwach, takich jak warstwa usługi (CanView / CanSerialize?). Ogólnie jednak uważam, że najbezpieczniejszą strategią autoryzacji jest również strategia „DRY-est”: utrzymuj autoryzację na jak najniższym poziomie, w najbardziej „powszechnym” lub „współdzielonym” kodzie, jak możesz (bez nadmiernego komplikowania reguł autoryzacji).

Pomyśl o alternatywie. Jeśli reguły autoryzacji są testowane i egzekwowane tylko w warstwie usług, pozostawiając słabe obiekty domeny do zgięcia do woli markotnych obiektów usług, często będziesz musiał egzekwować każdą regułę więcej niż raz, w wielu obiektach i wielu miejsca w każdym obiekcie oraz w bardziej skomplikowanym kodzie.

Ponadto, gdy Twój zespół analityczny zatrudnia firmę konsultingową do pisania usług raportowania przy użyciu obiektów domeny, nie musisz ufać tym programistom! (Lub cokolwiek. Budujesz dodatkowe usługi lub połączenia z tych samych obiektów z dowolnego powodu.) Nie będziesz chciał otworzyć dużej księgi reguł biznesowych i mieć nadzieję na prawidłowe egzekwowanie tych reguł ponownie ; chcesz, aby Twoja domena już je znała i egzekwowała.

svidgen
źródło
@ But Jeśli rozumiem twoją troskę - o to właśnie chodzi. Jeśli tylko „administrator” ma uprawnienie, zgodnie z regułami biznesowymi, do utworzenia Widget, ta sama reguła ma zastosowanie wszędzie. (Więc nie ryzykować pozwalając ktoś go zignorować!) Jeśli zasada nie stosuje się wszędzie, to naprawdę nie jest to reguła o Widgetsi wyłącznie Widgets . . Przesunąć reguły w dół tak daleko, jak to możliwe (poszczególne reguły); ale nie tak daleko, jak mogą sięgać „zasady” ... Czuję, że nie określam dobrze tego rozróżnienia. Ale powinno tam być rozróżnienie.
svidgen
Z mojego doświadczenia wynika, że ​​reguły autoryzacji są często częścią reguł biznesowych. W związku z tym „tak daleko, jak to możliwe” jest często moją warstwą domeny. Podejrzewam jednak, że to, gdzie „powinny” upaść Twoje reguły, jest tylko konsekwencją Twojej domeny, charakteru reguł i tego, jak firma o nich mówi.
svidgen