2008-09-25 17 views
8

Kilka lat temu opracowałem aplikację internetową, dla której chcieliśmy upewnić się, że użytkownicy nie udostępniają danych uwierzytelniających.Jak mogę się upewnić, że użytkownik jest zalogowany tylko raz?

Jedną z rzeczy, do których zdecydowaliśmy się, było zezwolenie użytkownikowi na zalogowanie się z jednego komputera na raz. Sposób, w jaki to zrobiłem, polegał na tym, żeby mieć mały element iframe pingujący serwer co N sekund; o ile serwer miał bicie serca dla określonego użytkownika (z określonego adresu IP), użytkownik ten nie mógł logować się z żadnego innego adresu IP.

Rozwiązanie, chociaż zatwierdzone przez mojego żłobka, zawsze wydawało mi się hacky. Wydaje się również, że łatwo byłoby go obejść.

Czy istnieje dobry sposób, aby upewnić się, że użytkownik aplikacji internetowej loguje się tylko raz? Szczerze mówiąc, nigdy nie rozumiałem, dlaczego zarząd chciał nawet tej funkcji. Czy wymuszanie tego w rozproszonych aplikacjach ma sens?

+0

czy kiedykolwiek napotkali Państwo problemy ze zmianą adresu IP klienta? lub czy Twoje środowisko było chronione przed tą kwestią? – Owen

+0

Nie mieliśmy problemów ze zmianą adresów IP. To była aplikacja dla naszych CSR, dla których kontrolowaliśmy adresy IP. –

Odpowiedz

11

Zaimplementowałem to, utrzymując hashtable aktualnie zalogowanych użytkowników, kluczem była nazwa użytkownika, wartość była ich ostatnim czasem działania.

Podczas logowania, po prostu zaznacz tę tablicę dla klucza, a jeśli istnieje, odrzuć login.

Gdy użytkownik robi cokolwiek, aktualizuje hashtable z czasem (jest to łatwe, jeśli staje się częścią podstawowej strony).

Jeśli czas w tablecie hashtable przekracza 20 minut bezczynności, usuwa się je. Możesz to zrobić za każdym razem, gdy hashtable jest sprawdzane, więc nawet jeśli miałeś tylko jednego użytkownika i próbowano zalogować się kilka godzin później, podczas tego początkowego czeku, usunąłoby je z tablicy hashtable za bezczynność.

Niektóre przykłady w C# (niesprawdzone):

public Dictionary<String,DateTime> UserDictionary 
{ 
    get 
    { 
     if (HttpContext.Current.Cache["UserDictionary"] != null) 
     { 
      return HttpContext.Current.Cache["UserDictionary"] as Dictionary<String,DateTime>; 
     } 
     return new Dictionary<String,DateTime>(); 
    } 
    set 
    { 
     HttpContext.Current.Cache["UserDictionary"] = value; 
    } 
} 

public bool IsUserAlreadyLoggedIn(string userName) 
{ 
    removeIdleUsers(); 
    return UserDictionary.ContainsKey(userName); 
} 

public void UpdateUser(string userName) 
{ 
    UserDictionary[userName] = DateTime.Now; 

    removeIdleUsers(); 
} 

private void removeIdleUsers() 
{ 
    for (int i = 0; i < UserDictionary.Length; i++) 
     { 
      if (user[i].Value < DateTime.Now.AddMinutes(-20)) 
       user.RemoveAt(i); 
     } 
} 
+0

Dlaczego zostało to odrzucone? Jest to jedyny rozsądny sposób na zrobienie tego. – FlySwat

+0

Brak pomysłu. Awans. – ceejayoz

+0

Podoba mi się twoje rozwiązanie. W rzeczywistości bezczynność (i świadomość, kiedy pozwolić użytkownikowi z powrotem) była jedną z rzeczy, które sprawiały mi najwięcej kłopotu. Podoba mi się pomysł, aby sprawdzenie "aktywności użytkownika" było częścią podstawowej funkcjonalności każdej strony. –

1

W bardzo bezpiecznej aplikacji może być wymagane takie działanie. Możesz tylko zwiększyć liczbę logowania dla zalogowanego użytkownika i adresu IP. Liczba nie powinna być równa 2. Jeśli tak, to zaloguj się do innego IP i którykolwiek z zalogowanych użytkowników zostanie wyrzucony. Nie spowoduje to jednak, że użytkownik-1 przekaże swoje dane uwierzytelniające użytkownikowi-2, będzie to po prostu frustrujące dla użytkownika-1, który wykona swoją pracę, jeśli użytkownik-2 zaloguje się gdzie indziej w tym samym czasie.

1

Nigdy nie znalazłem standardowego rozwiązania tego problemu. W jednej z moich aplikacji użyłem kombinacji Javascript + Java, aby zapewnić, że użytkownik może być zalogowany tylko jeden raz z określonego adresu IP (w rzeczywistości był to identyfikator sesji), ale w najgorszym przypadku działa, dla limitu czasu (ustawionego na 2 minuty) konto nie było dostępne. Nie wiem, dlaczego nie ma na to powszechnego sposobu.

3

patrząc tylko na IP może być zawodne. IIRC jest kilka stylów proxy, które wysyłają żądania wychodzące losowo na wiele adresów IP. W zależności od zakresu zastosowania może to mieć wpływ na Ciebie lub nie. Inne serwery proxy pokażą mnóstwo ruchu z jednego adresu IP.

Czas ostatniego logowania może również stanowić problem. Rozważmy uwierzytelnianie oparte na plikach cookie, w którym uwierzytelnianie plików cookie nie jest trwałe (dobrze). Jeśli przeglądarka ulegnie awarii lub jest zamknięta, użytkownik musi się ponownie zalogować, ale nie może to zrobić do czasu wygaśnięcia limitu czasu. Jeśli aplikacja jest przeznaczona do handlu akcjami, 20 minut niedziałających kosztuje i jest prawdopodobnie nie do przyjęcia.

Zazwyczaj można zakupić inteligentne zapory ogniowe/routery, które wykonają lepszą pracę niż ja lub ja jako jedno.Pomagają również w zapobieganiu atakom powtórek, kradzieży plików cookie itp. I można je skonfigurować tak, aby działały równolegle ze standardowymi mechanizmami na wybranej platformie internetowej.

1

Po prostu miałem ten problem.

Byliśmy tworzenia witryn Drupal, który zawierał aplikację Flex (zbudowany przez klienta), a on chciał następujące:

  1. przejrzystego logowanie z Drupal < -> Flex (! Bleh)
  2. nie współbieżne loginy !!

on przetestowany bzdura z każdego rozwiązania, i w końcu, to co zrobiliśmy:

  • Przeszliśmy wzdłuż identyfikator sesji na każdym adresie URL.
  • Gdy użytkownik zalogowany, możemy ustanowiła timestamp-IP-SessionID-loginu ślad
  • każdej stronie, DB został ping, a jeśli ten sam użytkownik został znaleziony w tym samym IP w/innego sessionid one starszy użytkownik został uruchomiony

Te rozwiązania spełniają rygorystyczne testy naszego klienta (2 komputery w jego house..he utrzymane nas do godziny znalezieniem małe zakamarki w kodzie zanim doszliśmy do tego rozwiązania)

4

Obracałbym problem i pozwalał na ostatnie logowanie kosztem wcześniejszego logowania, więc za każdym razem, gdy użytkownik się loguje, wypowiedz dowolne er sesje logowania, które może mieć.

To znacznie ułatwia wdrożenie, a ty wiesz, gdzie jesteś.

4

Po pracy nad "taką funkcją" trzeba być ostrzeżonym - to pułapka na słonia w skrajnych przypadkach, w której kończy się myśl, że masz ją przybita, a następnie ty lub ktoś inny mówi "ale co, jeśli ktoś zrobił X?" i zdajesz sobie sprawę, że musisz dodać kolejną warstwę złożoności.

Na przykład:

  • co jeśli użytkownik otworzy nową kartę z kopią sesji?
  • co, jeśli użytkownik otworzy nowe okno przeglądarki?
  • co się stanie, jeśli użytkownik się zaloguje, a przeglądarka ulegnie awarii?

i tak dalej ...

Zasadniczo istnieje szereg mniej lub bardziej hacky Żadne z rozwiązań, które są niezawodne i wszystkie, które będą trudne do utrzymania. Zwykle prawdziwym celem klienta jest inny uzasadniony cel bezpieczeństwa, taki jak "zatrzymaj użytkowników współdzielących konta".

Najlepszym pomysłem jest dowiedzieć się, jaki jest podstawowy cel i znaleźć sposób na jego rozwiązanie. I obawiam się, że wymaga to dyplomacji negocjacyjnej i innych podobnych "miękkich umiejętności", a nie wyruszenia w techniczną próbę dzikiej gęsi.,

Powiązane problemy