2013-01-04 2 views
5

Ho creato un servizio ServiceStack su Asp.Net che implementa l'autenticazione di base. Tutto sta funzionando bene sui percorsi di servizio. Sono in grado di accedere e ricevo i cookie di sessione che vengono convalidati nelle chiamate successive. Sto usando un HttpClient per quelle richieste.Autentica Hub SignalR con plug-in di autenticazione ServiceStack

Ho anche un Hub SignalR che viene eseguito sullo stesso servizio Asp.Net, ma il preside non è autenticato sui miei metodi Hub.

Fondamentalmente ciò che mi serve è che ServiceStack intercetti le chiamate nel mio hub e convalidi il cookie di sessione e compili il Context.User.Identity e lo contrassegni come autenticato. Se riesco a ottenere il set up, un semplice attributo [Authorize] sul mio hub farà il resto.

Ecco un esempio del mio codice:

// set up a HttpClient with a cookie container to hold the session cookie 
var cookieJar = new CookieContainer(); 
var handler = new HttpClientHandler { CookieContainer = cookieJar, UseCookies = true, UseDefaultCredentials = false }; 

var client = new HttpClient(handler) { BaseAddress = _baseUri }; 

client.DefaultRequestHeaders.Authorization = 
new AuthenticationHeaderValue("Basic", 
    Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password)))); 

// do client login and get response with session cookie... 
var response = client.PostAsync(...); 

// add the cookies to the SignalR hub connection 
var responseCookies = cookieJar.GetCookies(_baseUri); 
var cookieContainer = new CookieContainer(); 
foreach (Cookie cookie in responseCookies) 
{ 
    cookieContainer.Add(cookie); 
} 
_hubConnection = new HubConnection(_baseUri.ToString()) { CookieContainer = cookieContainer }; 

Dopo questa configurazione, i miei cookies di sessione vengono inviati al Hub ad ogni invocazione. In qualche modo ho bisogno che ServiceStack intercetti quelle richieste e imposti l'utente autenticato.

risposta

6

Lascia che ServiceStack esegua l'autenicazione e continui la sessione utente. Poi negli endpoint mozzo SignalR che necessitano di autenticazione inserire questo codice:

var cache = AppHostBase.Resolve<ICacheClient>(); 
var sess = cache.SessionAs<AuthUserSession>(); 
if (!sess.IsAuthenticated) 
    throw new AuthenticationException(); 
+0

Che ha funzionato in combinazione con il codice pubblicato originariamente in cui ho salvato i cookie di autenticazione nel contenitore del cookie SignalR. Grazie! – Kevin

2

Johan di opere risposta, ma non è molto comodo da indossare questo codice per ogni metodo e se lo metti nel costruttore hub, fallirà in il web alla pagina si aggiorna con l'eccezione "Solo richieste ASP.NET accessibili tramite Singletons".

Invece, ho scelto di creare un attributo personalizzato che offre un maggiore controllo sull'autorizzazione di chiamata di hub e metodo.

attributo

semplice sarebbe simile a questa:

[AttributeUsage(AttributeTargets.Class, Inherited = false)] 
public class AuthorizeServiceStack : AuthorizeAttribute 
{ 
    public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) 
    { 
     return CheckAuthorization(); 
    } 

    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod) 
    { 
     return CheckAuthorization(); 
    } 

    private static bool CheckAuthorization() 
    { 
     var cache = AppHostBase.Resolve<ICacheClient>(); 
     var sess = cache.SessionAs<AuthUserSession>(); 
     return sess.IsAuthenticated; 
    } 

} 

Come si può vedere, il codice è lo stesso in risposta di Johan ma funzionerà nel web così, assicurando che HttpContext.Current non è nullo quando si chiama cache.SessionAs