Sono avendo problemi simili qui, come nella mia app web uso un semplice sistema di autenticazione dei cookie che usa un approccio in stile AoP per il controllo qualsiasi controller con un attributo, quindi otterrà il contesto corrente (sia dal HttpContext.Current statico o dall'oggetto di chiamata di destinazione a seconda del tipo di intercettore) e quindi verificare che il cookie esista, contenga dati corretti, quindi verificare infine il token con db o cache, ecc.
In ogni caso questo approccio può essere utilizzato anche per Signalr, sebbene sia un po 'più a corto di energia e si sta utilizzando un'iniezione di dipendenza.Basterà avvolgere le chiamate hub con l'attributo desiderato, quindi configurare la configurazione DI/IoC per intercettare queste chiamate, quindi ottenere l'istanza hub all'interno dell'intercettore e ottenere il cookie (o il meccanismo di autenticazione personalizzato) dalla richiesta, verificare è tutto valido o no, e se non lo è allora lancia un new HttpException("403", "Not authenticated");
che dovrebbe respingere l'utente e tornare indietro prima che colpisca il tuo metodo hub, in questo modo puoi mettere la logica in un posto (il tuo intercettore o una classe l'intercettore consuma) quindi avvolgere semplicemente qualsiasi metodo che deve utilizzare questa autenticazione usando il proprio attributo.
Io uso Ninject e l'estensione di intercettazione, ma la maggior parte importante DI framework in questi giorni hanno una qualche forma di IoC plugin/estensioni, come Autofac, Windsor, Primavera ecc
Se non fossi felice andando giù il percorso di introdurre DI e/o AOP nel progetto corrente, forse potresti semplicemente creare un'istanza di hub personalizzata che contenga la tua logica di autenticazione e quindi usarla nei tuoi hub, quindi ok continuerai a chiamare manualmente alcune logiche di autenticazione all'interno di ciascuna metodo di hub che si desidera proteggere, ma la sua meno codice, in modo da qualcosa come:
public class AuthorisableHub : Hub
{
private ISomeAuthenticationToken GetSomeAuthenticationTokenFromRequest(Request request) // probably a SignalR specific request object
{
// Get your token from the querystring or cookie etc
}
private bool IsAuthenticationTokenValid(ISomeAuthenticationToken token)
{
// Perform some validation, be it simple or db based and return result
}
protected void PerformUserAuthentication()
{
var token = GetSomeAuthenticationTokenFromRequest(Context.Request);
var isRequestValid = IsAuthenticationTokenValid(token);
if(!isRequestValid)
{ throw new HttpException(403, "<Some forbidden message here>"); }
}
}
public class MyFancyPantsHub : AuthorisableHub
{
public void TellAllClientsSomethingSecret(ISecret secret)
{
PerformUserAuthentication();
// Do stuff with the secret as it should have bombed the user out
// before it reaches here if working correctly
}
}
Non è perfetto ma funzionerebbe (credo), inoltre sono sicuro di aver letto da qualche parte che gli Hub sono stati istanziati di nuovo per ogni richiesta, e se questo è vero, potresti eventualmente mettere questa logica nel tuo costruttore se vuoi per applicare l'autenticazione ad ogni azione all'interno dell'hub.
La speranza che ti aiuta, o ti dà delle idee ... sarebbe interessato a sapere come hai fatto a risolverlo alla fine.
Ho implementato la sicurezza basata su token passando un token utente generato con ciascuna richiesta SignalR tramite stringa di query (ad esempio $ .connection.hub.qs). Il client restituisce la chiave che esegue il cross-ref di un utente e sul server prendo il token e quindi carica l'utente dal cross ref. Funziona, ma è piuttosto brutto, in più non riesco a capire come applicare in modo pulito la sicurezza per non chiamare un metodo ValidateToken() che genera errori. –
Qualche aggiornamento su questo? Hai trovato un modo migliore per farlo ancora? Sto incontrando la stessa identica situazione. – BowserKingKoopa