2012-04-03 13 views
26

Uso el cliente SignalR Javascript y ASP.NET ServiceHost. Necesito que los concentradores y callbacks de SignalR solo sean accesibles para los usuarios que hayan iniciado sesión. También necesito poder obtener la identidad del usuario actualmente conectado desde el concentrador utilizando FormsIdentity desde HttpContext.Current.User.Protección de SignalR Calls

  1. ¿Cómo aseguro los concentradores para que solo los usuarios autenticados puedan usar SignalR?
  2. ¿Cómo obtengo la identidad del usuario que está conectado actualmente desde Hub?
+0

Otra forma de bloquear las URL de los señalizadores usando signalr 1.0 y Owin: http://eworldproblems.mbaynton.com/2012/12/securing-signalr-to-your-sites-users/ – mbaynton

Respuesta

19

Debe usar el this.Context.User.Identity disponible en el concentrador. See a related question

EDIT: Para evitar que los usuarios no autenticados:

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 
} 

editar # 2: Esto podría ser mejor, sólo devolverá un mensaje

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

Genial, ahora cualquier idea de cómo ¿Hubs seguros para que los usuarios no autenticados no se puedan conectar? – reach4thelasers

+0

@ reach4thelasers, por favor, mira mi edición. Eso es lo que probaría. – Aligned

+0

Después de ver la respuesta de @Jared Kells a continuación, recomendaría que si necesita forzar la autenticación en todos sus métodos para usar su enfoque, pero si solo lo necesita en algunos métodos, entonces use el mío. – Aligned

14

Puede bloquear el SignalR URL utilizando el PostAuthenticateRequest evento en su HttpApplication. Agregue lo siguiente a su Global.asax.cs

Esto bloqueará las solicitudes que no usen "https" o que no estén autenticadas.

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"); 
     } 
    }    
} 

Dentro de su hub puede acceder al usuario actual a través del objeto Context.

Context.User.Identity.Name 
4

Para la parte 1 de su pregunta que usted podría utilizar las anotaciones, como a continuación (Esto funcionó con 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

le falta algo de las otras respuestas es la capacidad de utilizar de SignalR construido en la costumbre clases de auth La documentación real de SignalR sobre el tema es terrible, pero dejé un comentario en la parte inferior de la página que detalla cómo hacerlo (Authentication and Authorization for SignalR Hubs).

Básicamente sustituir la clase de SignalR AuthorizeAttribute Siempre

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

A continuación, decorar sus centros con [CustomAuth] por encima de la declaración de la clase. A continuación, puede anular los siguientes métodos de autenticación para manejar:

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

Desde que estoy en los servidores IIS y tienen un esquema de autenticación personalizada, simplemente devuelve true desde el método AuthorizeHubConnection, porque en mi HttpModule de autenticación ya la authenicate/signalr/connect y/signalr/reconnect llamadas y guardar datos de usuario en un elemento HttpContext. Por lo tanto, el módulo maneja la autenticación en la llamada de conexión SignalR inicial (una llamada HTTP estándar que inicia la conexión del socket web).

Para autorizar llamadas en métodos concentradores específicos Compruebo nombres de métodos contra permisos guardados en HttpContext (es el mismo HttpContext guardado de la solicitud de conexión inicial) y devuelvo verdadero o falso en función de si el usuario tiene permiso para llamar a un determinado método.

En su caso, es posible que pueda utilizar el método AuthorizeHubConnection y decorar sus métodos de concentrador con funciones específicas, porque parece que está utilizando un sistema de identidad estandarizado, pero si algo no funciona bien, siempre puede revertir a la fuerza bruta con middleware HttpModule (u OWIN) y buscando datos de contexto en llamadas de websocket posteriores con AuthorizeHubMethodInvocation.