2013-03-19 9 views
6

Używam SignalR 1.0.1 jako rdzenia czatu dla aplikacji ASP.NET MVC3. Korzystanie z IIS 7.5


Istnieją dwie metody w kontrolerach MVC, które zapewniają dostęp do widoków czatu: 1. 1. Pierwsza metoda jest publiczna, umożliwiając anonimowym użytkownikom czatowanie - bez autoryzacji.
2. Dostęp do drugiej metody jest ograniczony atrybutem [Authorize] dla użytkowników domeny - agentów czatu.

Nie ma jawnie określonej autoryzacji w centrum.
W tym scenariuszu obejmowałem zarówno uwierzytelnianie Windows, jak i anonimowe w IIS.

Zaimplementowałam również niestandardowego Dostawcę Ról, który działa tylko w pamięci - nie zachowując niczego w bazie danych.SignalR - Identyfikator połączenia ma niepoprawny format podczas korzystania z uwierzytelniania Windows i anonimowego

Co się dzieje, że za pomocą „[Autoryzacja]” atrybut w metodzie kontrolera prowadzi do responsing 500 z Hub, zarówno gdy wywołanie pochodzi z autoryzowanego widzenia, a anonimowy jeden:

kupna (send jest metoda Hub dla wysyłanie wiadomości):

http://localhost:8101/signalr/send?transport=serverSentEvents&connectionToken=VIXEZzWQSn5SNlA8RUy4iaOPDFdvuPBjMvFBiG2FLfvfxF347XHwtapsEV5ndU4OEI0Xb64W2ZRXTqwBiL2CXg2_JlTaTJ2RnVOj4bjvx6tQaYhAqTaXs9k2853GYqzd0

Response:

The connection id is in the incorrect format.

Server stack trace: 
    at Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext context, String connectionToken) 
    at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context) 
    at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary2 environment) 
    at Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary2 environment) 
    at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute() 
    at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData)<br/><br/> 

jednak informacja, że ​​podłączenie do Hub działa prawidłowo, zwraca 200 OK:
http://localhost:8101/signalr/connect?transport=serverSentEvents&connectionToken=dYOwFxa1mkgdpzw-jitRpWq9oxRlrTet8U_dAzWjFQEdGNJfVXeG7Op0NZZwvznxeNdJCuPT75CKzQqI9HRPThV3uEDt-Z2qtIl9E02gF481&connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&tid=9

znalazłem trochę similiar wątek tutaj na stackoverflow:
signalr The connection id is in the incorrect format


z których rozumiem, że kiedy wywołując moją metodę Send, Hub przetwarza żądanie o numerze Identity innym niż używany do łączenia się z Hubem, LUB Hubem znajduje się GetConnectionId, że użytkownik faktycznie nie jest autoryzowany - ale jak sprawdza to założenie, kiedy nie ma autoryzacji określonej w samym Hubie?

Czy ktoś może rzucić trochę światła na to?

góry dzięki :)

Odpowiedz

9

SignalR znaki zarówno swój identyfikator połączenie i twój Identity razem w celu stworzenia nowego connectionToken każdym uruchomieniu nowego połączenia. Ten connectionToken jest następnie wysyłany do klienta SignalR jako część odpowiedzi negotiate.

każdym razem, kiedy złożyć wniosek do SignalR, czy to connect, reconnect lub send prośba, SignalR sprawdza, czy connectionToken odpowiada zarówno identyfikator połączenia swojego klienta i Identity.

Numer to zasadniczo token CSRF używany w celu uniemożliwienia osobom atakującym, które prowadzą strony trzecie, ukradkowe przekazywanie żądań SignalR w imieniu klientów współużytkowanych. Oczywiście to nie pomoże, jeśli włączyłeś obsługę Cross-domain SignalR, ale connectionToken nadal działa w tym przypadku tak samo.

Taylor's answer było poprawne. Powinieneś stop, a następnie start połączyć się z SignalR, gdy zmieni się Identity klienta. Spowoduje to wymuszenie nowego żądania, które da klientowi nowy identyfikator połączenia z nowym connectionToken podpisanym z zaktualizowanym klientem Identity.

P.S. Zgłoszenie wysłane przez serwer nie powiodło się, ponieważ zostało ustanowione przed zmianą Identity klienta. Parametr connectionToken jest sprawdzany tylko na żądanie, ale zdarzenia wysłane przez serwer utrzymują odpowiedź otwartą w nieskończoność.

+0

Dzięki za wyjaśnienie. – mskuza

+0

Ale najtrudniejsza część, którą znalazłem, polega na tym, że zarówno 'connect', jak i' send' są wykonywane po autoryzacji - metoda kontrolera wywołań użytkownika ozdobiona '[Authorize]' co zapewnia mu widok, gdzie ma miejsce wywołanie Hub - tak podczas wywoływania 'connect' z Javascript, użytkownik jest już autoryzowany. Rozumiem, że 'Identity' zmienia się przed każdym wywołaniem do Hub - podczas wykonywania akcji MVC. – mskuza

+0

Patrząc na twój ślad stosu, jest całkiem jasne, że "Tożsamość" Twojego użytkownika zmieniła się pomiędzy żądaniem "negocjuj" i "wyślij". Mogło to nastąpić za pośrednictwem żądania AJAX lub limitu czasu sesji. – halter73

3

To wszystko prawda, co powiedziałeś i faktycznie ma to miejsce w moim wydaniu.

Ale znalazłem również główną przyczynę:
Jednym z głównych założeń podczas projektowania było umożliwienie anonimowym użytkownikom korzystania z czatu bez potrzeby logowania, a użytkownicy zewnętrzni (agenci) do logowania się do ograniczony obszar czatu przy użyciu jego poświadczeń systemu Windows.

Tak więc w Menedżerze usług IIS włączono zarówno uwierzytelnianie anonimowe (umożliwiające anonimowym użytkownikom korzystanie z czatu), jak i uwierzytelnianie systemu Windows (umożliwiając agentom dostęp przy użyciu ich poświadczeń systemu Windows).
Aplikacja MVC jest skonfigurowana do używania uwierzytelniania systemu Windows - wspomnianego atrybutu [Authorize], ale tylko w celu ograniczenia dostępu do widoku czata agenta.

Co właściwie dzieje się z powyższej konfiguracji jest:
1. Gdy klient (środek) wnioski ograniczone View (powiedzmy to /Chat/Agent) atrybut [Authorize] inicjuje uwierzytelniania (Windows)
2. Po stronie klienta JavaScript żąda Negotiate, co generuje connectionId i wiąże go z Windows klienta Identity
3. Oto Najtrudniejsze: Ponieważ Hub nie używa żadnego uwierzytelnienia wyraźnie, nazywając send metody nie powoduje każde żądanie uwierzytelnienia - IIS uwierzytelnianie anonimowe trwa precedency przed uwierzytelniania systemu Windows, a send wniosek jest wysłane z anonimowym Identity - ale w rzeczywistości Hub connectionId jest związane Identity przeszedł w punkcie 2.

Taki scenariusz prowadzi do sytuacji opisałeś - connect nazywa z innego Identity niż send i Hub zwraca The connection id is in the incorrect format.

Powiązane problemy