SignalR - Send message to user using UserID Provider

15,868

I have not looked into SignalR 2.0 but I think this is an extension of what the previous versions of SignalR used to have. When you connect to the hub you can decorate it with an Authorize attribute

[HubName("myhub")]
[Authorize]
public class MyHub1 : Hub
{
    public override System.Threading.Tasks.Task OnConnected()
    {
        var identity = Thread.CurrentPrincipal.Identity;
        var request = Context.Request;
        Clients.Client(Context.ConnectionId).sayhello("Hello " + identity.Name);
        return base.OnConnected();
    }
}

As you can see you are able to access the Identity of the user accessing the Hub. I believe the new capability would be nothing more than an extension of this. Since the connection is always kept alive between the client and the hub you will always have the principal identity which will give you the UserId.

Share:
15,868

Related videos on Youtube

hatcyl
Author by

hatcyl

Updated on September 15, 2022

Comments

  • hatcyl
    hatcyl over 1 year

    Using SignalR, I believe I should be able to send messages to specific connected users by using UserID Provider

    Does anyone have an example of how this would be implemented? I've searched and searched and can not find any examples. I would need to target a javascript client.

    The use case is, users to my site will have an account. They may be logged in from multiple devices / browsers. When some event happens, I will want to send them a message.

    • hatcyl
      hatcyl over 10 years
      Uhm ... maybe I misunderstood their documentation. Before you could manually sync user ids to connection ids and broadcast appropriately.I thought the point of the UserID Provider was to eliminate this manual tracking. I though it would somehow know who the user was based on the the same User that the normal Authentication uses.
    • davidfowl
      davidfowl over 10 years
      The point is exactly that, if you have the user name, you don't have to track anything. By default it'll use the user name (if you're using some form of auth that sets the principal)
  • hatcyl
    hatcyl over 10 years
    In debugging my application, when connecting from my javascript client , both Thread.CurrentPrincipal.Identity and Context.Request are empty. Is there a special way to connect from javascript so that it knows it needs that info?
  • Gjohn
    Gjohn over 10 years
    Well, how are you logging into your application? Do you have any piece that is doing the authentication?
  • hatcyl
    hatcyl over 10 years
    I've been reading up on this. For my MVC and WebApis I have an HttpModule which does Basic Auth and sets the Principal from there. This is working well for the APIs and Views in MVC. However, I am reading that with the SignalR connections I think those Authorization headers do not get sent. So that may be the underlying issue I am facing.
  • Gjohn
    Gjohn over 10 years
    There should be no reason that your Hub would not be able to use that. Have you added the GlobalHost.HubPipeline.RequireAuthentication(); to your global.asax or wherever you have registered your hub?
  • hatcyl
    hatcyl over 10 years
    Just tries. No go. Thanks though.
  • hatcyl
    hatcyl over 10 years
    Have not tried, but will. However, I should not need to "require" it right? I should be able to have Authorized as well as Anonymous users?
  • Gjohn
    Gjohn over 10 years
    Not if you added the GlobalHost.HubPipeline.RequireAuthentication(); that will force the users to be authenticated in which case anonymous uses won't be able to access your hub.
  • Gjohn
    Gjohn over 10 years
    That being said - you should be able to add your own custom authorization to handle anonymous users. You would just need to have a way of ensuring that those users would have a valid userId - even something that is temporarily created. see - asp.net/signalr/overview/signalr-20/security/hub-authorizati‌​on
  • hatcyl
    hatcyl over 10 years
    Thanks, I'll try some of the suggestions and keep researching. I'll keep you guys posted.
  • hatcyl
    hatcyl over 10 years
    I think I figured it out following your suggestions. The browser by default when connecting does not send Authorization Headers. Only once it receives the 401 error will it try again sending the Authorization. By adding the Authorized attribute to my Hub, the browser was forced to send the Authorization headers and now I am able to access Context.User correctly.
  • Gjohn
    Gjohn over 10 years
    @hatcyl - glad I could help.
  • MemeDeveloper
    MemeDeveloper almost 10 years
    as dfowler says no need to do this : "To use this default implementation, first register it in GlobalHost when the application starts up:" as its the default.