2013-03-19 15 views
6

Uso SignalR 1.0.1 come nucleo di chat per l'applicazione ASP.NET MVC3. Utilizzo di IIS 7.5

Esistono due metodi nel controller MVC che fornisce l'accesso alle viste di chat:
1. Il primo metodo è pubblico e consente agli utenti anonimi di chattare, senza autorizzazione.
2. L'accesso al secondo metodo è limitato con l'attributo [Authorize], per gli utenti del dominio - agenti di chat.

Non esiste un'autorizzazione esplicitamente specificata nell'hub.
Per questo scenario ho coinvolto sia l'autenticazione Windows che quella anonima su IIS.

Ho implementato anche il fornitore di ruoli personalizzato, che funziona solo in memoria, non persistendo nulla nel database.SignalR - L'ID connessione è nel formato errato quando si utilizza l'autenticazione Windows e anonima

Succede che usando '[Autorizza]' attributo nel metodo di controllo porta a responsing 500 dal mozzo, sia quando chiamata in arrivo dalla vista autorizzato, e l'anonimo uno:

Request (send è metodo Mozzo per invio di messaggi):

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

risposta:

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/> 

Ma notate, che la connessione a Hub funziona bene, restituisce 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

ho trovato poco filo simile qui su StackOverflow:
signalr The connection id is in the incorrect format


da cui ho capito, che quando invocando il mio metodo Send, l'Hub elabora la richiesta con Identity diversa da quella utilizzata per connettersi all'Hub, oppure i riferimenti dell'GetConnectionId dell'hub, in realtà l'utente non è autorizzato, ma come verifica tale ipotesi, quando non esiste un'autorizzazione specificata sull'hub stesso?

Qualcuno può mettere un po 'di luce su questo?

Grazie in anticipo :)

risposta

9

segni SignalR sia la vostra connessione ID e il Identity insieme al fine di creare un nuovo connectionToken ogni volta che si avvia una nuova connessione. Questo connectionToken viene quindi inviato al client SignalR come parte della risposta negotiate.

Ogni volta che si effettua una richiesta di SignalR, sia che si tratti di un connect, reconnect o send richiesta, SignalR verifica che la connectionToken partite sia id connessione del vostro cliente e Identity.

Lo connectionToken è essenzialmente un token CSRF utilizzato per impedire a utenti malintenzionati che eseguono siti Web di terze parti di effettuare in modo surrettizio richieste SignalR per conto di client condivisi. Ovviamente questo non aiuta se hai abilitato il supporto per il dominio incrociato di SignalR, ma lo connectionToken funziona ugualmente in questo caso.

Taylor's answer era corretto. È necessario stop e quindi start la connessione SignalR quando le modifiche del client Identity. Ciò imporrà una nuova richiesta negotiate che fornirà al client un nuovo ID di connessione con un nuovo connectionToken firmato con il Identity aggiornato del client.

P.S. La richiesta di eventi inviati dal server connect non ha esito negativo poiché è stata stabilita prima della modifica del Identity del client. Lo connectionToken viene controllato solo quando la richiesta viene ricevuta, ma gli eventi inviati dal server mantengono la risposta aperta indefinitamente.

+0

Grazie per chiarimenti. – mskuza

+0

Ma la parte difficile che ho trovato è che sia 'connect' che' send' vengono eseguiti dopo l'autorizzazione - l'utente chiama il metodo del controller decorato con '[Authorize]' cosa gli fornisce una vista dove si chiama Hub, quindi quando si chiama 'connect' da Javascript, l'utente è già autorizzato. La mia comprensione è che 'Identity' è cambiato prima di qualsiasi chiamata all'Hub - durante l'esecuzione dell'azione MVC. – mskuza

+0

Osservando la traccia dello stack, è abbastanza chiaro che l'identità dell'utente è cambiata tra la richiesta 'negotiate' e' send'. Questo potrebbe essere successo tramite una richiesta AJAX o un timeout di sessione. – halter73

3

Questo è tutto vero quello che hai detto e in realtà si svolge nel mio problema.

Uno dei principali presupposti in fase di progettazione era consentire a entrambi gli utenti anonimi di utilizzare la chat senza necessità di accesso e gli utenti back-end (agenti) per accedere a area riservata della chat usando le loro credenziali di Windows.

Così sul gestore IIS ho abilitato sia l'autenticazione anonima (che consente agli utenti anonimi di utilizzare la chat) sia l'autenticazione di Windows (consentendo agli agenti di accedere utilizzando le loro credenziali di Windows).
L'applicazione MVC è configurata per utilizzare l'autenticazione di Windows - l'attributo [Authorize] menzionato nella domanda, ma solo per limitare l'accesso per la vista dell'agente della chat.

Cosa succede in realtà con la configurazione sopra è:
1. Quando client (agente) richieste di Fila (diciamo che è /Chat/Agent) l'attributo [Authorize] inizializza autenticazione (Windows)
2. JavaScript lato client richiede Negotiate, ciò che genera connectionId e lo associa con Windows del client Identity
3. Ecco la parte difficile: Perché Hub non utilizza alcuna autenticazione in modo esplicito, chiamando send metodo non comporta alcuna richiesta di autenticazione - IIS l'autenticazione anonima prende precedenza prima di autenticazione di Windows, e send richiesta è inviato con l'anonimo Identity - ma in Hub effettivo connectionId è legato alla Identity approvata nel punto 2.

Questo scenario porta a situazione che hai descritto - connect è chiamato con diversi Identity rispetto send e Hub restituisce The connection id is in the incorrect format.

Problemi correlati