Search code examples
c#asp.netiissignalr-hub

Isolate users in signalR hub by domain


I have a web application that is a single IIS installation (This isn't changing), but has a dynamic collection of subdomains. Each subdomain has its own user accounts.

The problem I am running into is that when I run signalR on it, it treats all sub-domains as the same domain, so users who just so happen to have the same user name will get each others messages.

This is causing me an security violation issue between domain accounts.

So far my best guess solutions for this have different levels of risks and problems.

  1. Each user gets their own group, build the group name with the sub-domain name + user name.
    1. List item this minimizes the risk of collision but doesn't remove it.
    2. Using a Guid for the domain name, and reserving the first n-characters for the guid reduces the risk even further, but now for each user online I now have a group formed.
  2. On the owin start, spin up a new hub that represents each domain.
    1. Each time I add a subdomain, I will have to restart the application to add the new hub. Right now, I don't have to do anything to add subdomains the DNS is supporting the wildcard, and the host header in IIS is blank. All works except for the lack of subdomain awareness in SignalR.
  3. Build a custom hub class, that makes the client collection domain aware, like the rest of the application.
    1. This seems to be the cleanest, but by far, most time consuming. It also poses the highest risk of bugs, since I will have to compose a larger collection of QA tests beyond the TDD unit testing.
  4. Last option, don't use SignalR, build my own long poll API.
    1. This is the hardest one to accept, since it is the highest bandwidth and most exposed process. A basic survey of our target users shows that they are using websocket supporting browsers, so why would we purposely increase bandwidth or create new latency.

To see this failure, just grab the simple chat demo at ASP.NET/SignalR, and run it on your local computer under two different browsers (FF and IE for my core tests), and have one call http:\localhost and the other call http:\yourcomputername. You will need IIS not IIS Express for a proper test.


Solution

  • My 2 cents: build your own implementation of IUserIdProvider, from there it should be easy to inspect each request and generate a unique user id across multiple domains which you would return, this way SignalR would know to whom to associate each request correctly. It'd be a simple and not invasive solution. You can check here for more detail.