2013-01-04 19 views
5

Utworzyłem usługę ServiceStack na górze Asp.Net, która implementuje uwierzytelnianie podstawowe. Wszystko działa dobrze na trasach usług. Mogę się zalogować i otrzymuję ciasteczka sesyjne, które są sprawdzane przy kolejnych połączeniach. Używam HttpClient dla tych żądań.Uwierzytelnianie SignalR Hub przy użyciu ServiceStack Authentication Plugin

Posiadam również Hub SignalR, który działa na tej samej usłudze Asp.Net, ale Zleceniodawca nie jest uwierzytelniony w moich metodach Hub.

Zasadniczo potrzebuję, aby ServiceStack przechwycił połączenia do mojego centrum i zweryfikował plik cookie sesji i zapełnił Context.User.Identity i oznaczył go jako uwierzytelniony. Jeśli uda mi się uzyskać tę konfigurację, prosty atrybut [Authorize] w moim hubie zajmie się resztą.

Oto przykład z mojego kodu:

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

Po tej konfiguracji, moi sesyjne ciasteczka są wysyłane do koncentratora na każdym wywołaniu. W pewnym momencie potrzebuję ServiceStack do przechwycenia tych żądań i ustawienia uwierzytelnionego użytkownika.

Odpowiedz

6

Pozwól usłudze ServiceStack wykonać uwierzytelnianie i kontynuować sesję użytkownika. Następnie w punktach końcowych piast SignalR które wymagają uwierzytelnienia umieścić ten kod:

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

To działało w połączeniu z oryginalnie opublikowanym kodem, w którym zapisałem ciasteczka autoryzacyjne do kontenera Cookal SignalR. Dzięki! – Kevin

2

Johan dzieła odpowiedzi, ale nie jest to bardzo wygodne, aby umieścić ten kod do każdej metody i jeśli umieścić go w konstruktorze piasty, to nie w odświeżanie strony na stronie z "wyjątkiem tylko zgłoszeń ASP.NET dostępnych przez Singletons".

Zamiast tego wybrałem tworzenie niestandardowego atrybutu, który zapewnia większą kontrolę nad autoryzacją wywołania metody i koncentratora.

atrybut

Najprostszy będzie wyglądać następująco:

[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; 
    } 

} 

Jak widać, kod jest taki sam, jak w odpowiedzi Johana ale to będzie działać w sieci, jak również, zapewniając, że HttpContext.Current nie jest null podczas wywoływania cache.SessionAs

Powiązane problemy