2010-12-16 26 views
13

Mam aplikacji ASP.NET MVC z kontrolerem, który wygląda mniej więcej tak:ASP.NET MVC Controller Konstruktor wezwany przed uwierzytelnianiem

[Authorize] 
public class MyController : Controller 
{ 
IMyRepository myRepository; 
public MyController(IMyRepository myRepository) 
{ 
    this.myRepository = myRepository; 
} 

... 
} 

Zauważyłem, że konstruktor zostanie wywołany przed uwierzytelnieniu użytkownika, więc jeśli odwiedzasz stronę po raz pierwszy, przed wywołaniem przekierowania do ekranu logowania zostanie wywołany konstruktor. Istnieje wiele problemów z tym związanych, strona logowania ładuje się wolniej, witryna jest bardziej narażona na ataki DOS i jestem trochę zaniepokojony nieuwierzytelnionymi, nieautoryzowanymi użytkownikami, którzy mogą wywołać kod "za ścianą".

Mogę sprawdzić nadchodzące żądanie w konstruktorze i kaucję, chyba że użytkownik jest uprawniony, ale używam IOC (Windsor), co sprawia, że ​​nieco trudne, moje repozytorium zostanie zainicjowane niezależnie od tego, czy I przechowuj instancję, więc pozostawię sprawdzanie uwierzytelnienia w każdym konstruktorze repozytorium. Czy istnieje prosty sposób uzyskania .NET MVC do uwierzytelnienia użytkownika przed w celu wywołania konstruktora? Myślę o dodaniu do kontrolera [PrincipalPermission(SecurityAction.Demand, Authenticated = true)], ale może być jeszcze lepszy sposób.

EDIT:

Ok, nie jest zbyt szczęśliwy z tego powodu, ale przedstawienie musi trwać teraz. Nie mogę opóźnić inicjowania repozytorium do czasu późniejszego z poziomu kontrolera. Kiedy twój kontroler używa IOC, tak jak w moim przykładzie, otrzymujesz już zainicjowaną implementację interfejsu repozytorium w momencie utworzenia kontrolera. Gdybym miał kontrolę nad tworzonym repozytorium, mógłbym łatwo wywołać IsAuthenticated, bez potrzeby stosowania nowej metody. Aby przejąć kontrolę nad inicjalizacją repozytorium, musiałbyś zaimplementować jakąś leniwą/późną inicjalizację w samym repozytorium w każdej implementacji. Nie podoba mi się to rozwiązanie, ponieważ powoduje niepotrzebną złożoność i, co ważniejsze, sprzężenie między kontrolerem a repozytorium. Implementacje repozytorium mogą być używane w innych kontekstach, w których inicjalizacja lenna nie ma sensu IMHO.

+1

Pod warunkiem, że Twój konstruktor implementacji IMyRepository był lekki, nie widzę tu poważnego problemu (np. Jeśli jest to kosztowny proces konfiguracji rzeczywistego połączenia z twoim zapleczem, to zrób to leniwie, tzn. Po pierwszym odczytaniu/zapisaniu). Nie jesteś już tak wyeksponowany na stronie logowania, ponieważ to również tworzy instancję kontrolera i prawdopodobnie uzyskuje dostęp do magazynu pomocniczego w celu zweryfikowania poświadczeń. – Lazarus

+1

@Lazarus Ale co, jeśli zależność od mojego kontrolera wymaga dostępu do niezerowej nazwy użytkownika (to znaczy, że użytkownik musi być uwierzytelniony w tym momencie). Obecnie używam do tego instancji 'Lazy ', ale nienawidzę tego. Wydaje mi się, że byłoby zbyt wiele sensu, aby uwierzytelnić użytkownika przed dotarciem do kontrolera. – julealgon

Odpowiedz

0

Paweł

konkretyzacja regulatora jest wiele wiele procesów przed wszelkimi działaniami na kontroler jest wymagalne. nawet gdyby osoba atakująca próbowała odnieść korzyść z tego czasu pomiędzy instancją a ekranem logowania, działanie kontrolera byłoby możliwe tylko wtedy, gdyby akcja miała takie uprawnienie, tzn. zakładam, że twoje działania lub kontroler wszystkie mieć na sobie atrybut [Authorize].

Nie sądzę, że trzeba się o to zbytnio martwić i można spokojnie spać, chociaż "rozumiem twoją oczywistą ciekawość.

4

Sterownik musi być utworzony w instancji przed autoryzacją, ponieważ może działać jako własny filtr autoryzacji za pomocą metody OnAuthorization. Zmiana tego zachowania wymagałaby zastąpienia niektórych głównych części rurociągu mvc. Czy istnieje jakiś szczególny powód, dla którego uważasz, że AuthorizedAttribute może nie wykonać swojej pracy?

+0

Moje kontrolery mają raczej ciężkie konstruktory i nie chcę, aby nieuwierzytelnieni użytkownicy mogli zainicjować kod. Rozumiem, że autoryzacja nie może wystąpić przed utworzeniem kontrolera, po prostu chcę wcześniej wykonać uwierzytelnianie. Wezmę wszystko, co znajdę tutaj, kiedy skończę. – Paul

+0

Och, jeśli chcesz tylko uniemożliwić nieuwierzytelnionym użytkownikom dotarcie do kontrolera, możesz zajrzeć do pisania niestandardowej trasy, która nie pasuje do nieuwierzytelnionych klientów. – marcind

+2

Inną opcją, którą można rozważyć, jest zainicjowanie repozytorium w trybie OnActionExecuting metody kontrolera zamiast w konstruktorze. – marcind

0

Pod względem ataków DOS, to naprawdę nie powinno mieć znaczenia - po pierwszym trafieniu, które widzi się dużo podczas rozwoju, instancja kontrolera powinna być tania. Cóż, chyba że jesteś DDOSing się przez konstruktora do rzeczywistej pracy, takich jak wstępne buforowanie wyszukiwań bazy danych. . .

Powiązane problemy