2013-11-26 10 views
5

Mam SignalR uruchomiony na mojej aplikacji MVC 4, która korzysta z uwierzytelniania formularzy. Mam czas oczekiwania na cookie z wygaśnięciem po wygaśnięciu do 20 minut.Wyjątek SignalR "Nierozpoznana tożsamość użytkownika Tożsamość użytkownika nie może się zmienić podczas aktywnego połączenia SignalR."

Mam funkcję javascript, która działa na czasomierzu, więc po 20 minutach i 1 sekundzie odświeża stronę, a użytkownik jest przekierowywany na stronę logowania. Ważne jest, że robię to ze względów bezpieczeństwa i działa dobrze.

Mój problem polega na tym, że SignalR rzuca wyjątek InvalidOperation, ponieważ tożsamość użytkownika uległa zmianie. Rozumiem, dlaczego to robi, ale nie jestem pewien, jak tego uniknąć.

Próbowałem wywoływać $ .connection.hub.stop(); przed ponownym załadowaniem strony, ale nie działa. Próbowałem wywoływać to 5 sekund przed wygaśnięciem pliku cookie, ale to tylko ponownie aktywuje sesję.

Wszelkie pomysły będą mile widziane!

Dzięki John

Odpowiedz

2

byłem odpowiada David Fowler (autor SignalR) na Github i powiedział, że nie był to łatwy sposób na rozwiązanie tego.

Aby obejść problem, zaimplementowałem akcję kontrolera Silent Logout, która po prostu zabija sesję użytkowników.

[HttpPost] 
    [AjaxOnly] 
    public ActionResult SilentLogOff() 
    { 
     _unitOfWork.WebSecurity.Logout(); 

     return Json(new 
     { 
      IsSuccess = true, 
     }); 
    } 

Następnie ustawiłem timer JS na 10 sekund krótszy niż limit czasu uwierzytelniania formularzy. Po wygaśnięciu zatrzymuje połączenie z urządzeniem SignalR, wykonuje test POST na działanie SilentLogout, a następnie ponownie ładuje stronę.

SetLogoutTimer: function() { 

    var formsTimeoutValue = $("#hdnRefreshTimeout").val(); 

    clearTimeout("formsTimeoutTimer"); 

    var formsTimeoutTimer = setTimeout(function() { 
     $.connection.hub.stop(); 

     AppName.Authenticated.SilentLogoutUser(); 

    }, formsTimeoutValue); 
} 

SilentLogoutUser: function() { 
    var url = $("#logout a").attr("data-bind-silent-url"); 
    $.ajax({ 
     type: "POST", 
     url: url, 
     success: function (response) { 
      if (response.IsSuccess === true) { 
       window.location.reload(true); 
      } 

     } 
    }); 
} 

Powoduje prawidłowego zachowania się, że nie ma wyjątków SignalR, a użytkownik jest przekierowywany do poprzedniej strony byli na po ponownym poświadczenia.

+0

Czy to naprawdę rozwiązało problem? Czy możesz napisać jakiś kod? – WebDever

+0

Dodano próbki kodu Hi. I tak to działa. To jest rozwiązanie javascript, więc nie będzie pasowało do wszystkich scenariuszy. W mojej aplikacji użytkownik nie może się zalogować, chyba że włączony jest javascript. –