2012-04-03 29 views
26

Używam klienta JavaScript SignalR i programu ASP.NET ServiceHost. Potrzebuję, aby węzły SignalR i wywołania zwrotne były dostępne tylko dla zalogowanych użytkowników. Potrzebuję również móc uzyskać tożsamość aktualnie zalogowanego użytkownika z koncentratora przy użyciu FormsIdentity z HttpContext.Current.User.Zabezpieczanie połączeń SignalR

  1. Jak zabezpieczyć koncentrator, aby tylko uwierzytelnieni użytkownicy mogli korzystać z SignalR?
  2. Jak uzyskać tożsamość aktualnie zalogowanego użytkownika z koncentratora?
+0

Kolejny sposób na blokowanie adresów URL za pomocą signalr 1.0 i Owina: http://eworldproblems.mbaynton.com/2012/12/securing-signalr-to-your-sites-users/ – mbaynton

Odpowiedz

19

Powinieneś użyć this.Context.User.Identity dostępnego z Hub. See a related question

EDIT: Aby zatrzymać nieuwierzytelnionych użytkowników:

public void ThisMethodRequiresAuthentication() 
{ 
    if(!this.Context.User.Identity.IsAuthenticated) 
    { 
    // possible send a message back to the client (and show the result to the user) 
    this.Clients.SendUnauthenticatedMessage("You don't have the correct permissions for this action."); 
    return; 
    } 

    // user is authenticated continue 
} 

EDIT # 2: To może być lepiej, po prostu wrócić wiadomość

public string ThisMethodRequiresAuthentication() 
    { 
     if(!this.Context.User.Identity.IsAuthenticated) 
     { 
     // possible send a message back to the client (and show the result to the user) 
     return "You don't have the correct permissions for this action."); 

     // EDIT: or throw the 403 exception (like in the answer from Jared Kells (+1 from me for his answer), which I actually like better than the string) 
     throw new HttpException(403, "Forbidden"); 
     } 

     // user is authenticated continue 

     return "success"; 
    } 
+1

Świetnie, teraz każdy pomysł, jak bezpieczne koncentratory, aby nieuwierzytelnieni użytkownicy nie mogli się połączyć? – reach4thelasers

+0

@ reach4thelasers zobacz moją edycję. Właśnie tego chciałbym spróbować. – Aligned

+0

Po zapoznaniu się z odpowiedzią @ Jareda Kellsa poniżej, polecam, jeśli potrzebujesz wymusić uwierzytelnianie na wszystkich swoich metodach, aby użyć jego podejścia, ale jeśli potrzebujesz tego tylko na kilka sposobów, użyj mojego. – Aligned

14

można zablokować w dół SignalR URL za pomocą PostAuthenticateRequest wydarzenie na Twojej HttpApplication. Dodaj poniższe do pliku Global.asax.cs

Spowoduje to zablokowanie żądań, które nie używają "https" lub nie są uwierzytelniane.

public override void Init() 
{ 
    PostAuthenticateRequest += OnPostAuthenticateRequest; 
} 

private void OnPostAuthenticateRequest(object sender, EventArgs eventArgs) 
{ 
    if (Context.Request.Path.StartsWith("/signalr", StringComparison.OrdinalIgnoreCase))    
    { 
     if(Context.Request.Url.Scheme != "https") 
     { 
      throw new HttpException(403, "Forbidden"); 
     } 

     if (!Context.User.Identity.IsAuthenticated) 
     { 
      throw new HttpException(403, "Forbidden"); 
     } 
    }    
} 

Wewnątrz koncentratora można uzyskać dostęp do bieżącego użytkownika za pośrednictwem obiektu kontekstowego.

Context.User.Identity.Name 
4

Dla części 1. Państwa pytania można użyć adnotacji jak poniżej (ten pracował z SignalR 1.1):

[Authorize] 
public class MyHub : Hub 
{ 
    public void MarkFilled(int id) 
    { 
     Clients.All.Filled(id); 
    } 
    public void MarkUnFilled(int id) 
    { 
     Clients.All.UnFilled(id); 
    } 
} 
0

Coś brakuje innych odpowiedzi jest możliwość korzystania SignalR wbudowanego w zwyczaju klasy auth. Faktyczna dokumentacja SignalR na ten temat jest okropna, ale na dole strony zostawiłem komentarz opisujący, jak to zrobić (Authentication and Authorization for SignalR Hubs).

Zasadniczo zastąpić dostarczonym klasa SignalR AuthorizeAttribute

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] 
public class CustomAuthAttribute : AuthorizeAttribute 

Następnie udekorować swój piast z [CustomAuth] wyżej deklaracji klasy. Następnie można zastąpić następujące metody do obsługi uwierzytelniania:

bool AuthorizeHubConnection(HubDescriptor hubDesc, IRequest request); 
bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubContext, bool appliesToMethod); 

Ponieważ jestem na serwerach IIS i mieć własnego schematu uwierzytelniania, po prostu wrócić prawdziwe od sposobu AuthorizeHubConnection, ponieważ w moim Auth HttpModule już authenicate/signalr/connect i/signalr/reconnect wywołania i zapisz dane użytkownika w elemencie HttpContext. Dlatego moduł obsługuje uwierzytelnianie podczas początkowego połączenia SignalR (standardowe połączenie HTTP inicjujące połączenie z gniazdem sieciowym).

Aby autoryzować połączenia dla określonych metod koncentratora, sprawdzam nazwy metod względem uprawnień zapisanych w HttpContext (jest to ten sam HttpContext zapisany od początkowego żądania połączenia) i zwracam true lub false w zależności od tego, czy użytkownik ma uprawnienia do wywoływania pewnych metoda.

W twoim przypadku możesz faktycznie używać metody AuthorizeHubConnection i udekorować swoje metody koncentratora konkretnymi rolami, ponieważ wygląda na to, że używasz znormalizowanego systemu tożsamości, ale jeśli coś nie działa poprawnie, zawsze możesz wrócić do brute force z HttpModule (lub OWIN) middleware i wyszukiwanie danych kontekstowych w kolejnych wywołaniach websocket za pomocą AuthorizeHubMethodInvocation.