Question

I have two hubs in a web role,

1) external facing hub meant to be consumed over https external endpoint for website users.

2) intended to be connected to over http on an internal endpoint by worker roles.

I would like the ability to secure access to the hubs somehow.

Is there anyway I can check to see what connection type the connecting user/worker role is using and accept/deny based on this?

Another method I thought of was perhaps using certificate authentication on the internal hubs but i'd rather not have to for speed etc.

GlobalHost.DependencyResolver.UseServiceBus(connectionString, "web");

// Web external connection
app.MapSignalR("/signalr", new HubConfiguration() 
     { EnableJavaScriptProxies = true, EnableDetailedErrors = false });

// Worker internal connection
app.MapSignalR("/signalr-internal", new HubConfiguration() 
     { EnableJavaScriptProxies = false, EnableDetailedErrors = true});    

EDIT: I've included my own answer

Was it helpful?

Solution 2

I ended up probing the request environment variables and checking the servers localPort and request scheme in a custom AuthorizeAttribute. The only downside to this at the moment is that the javascript proxies will still generate the restricted hub info. But i'm working on that :).

I'll leave the question open for a bit to see if anyone can extend on this.

public class SignalrAuthorizeAttribute : Microsoft.AspNet.SignalR.AuthorizeAttribute, Microsoft.AspNet.SignalR.IDependencyResolver
{
    public override bool AuthorizeHubConnection(Microsoft.AspNet.SignalR.Hubs.HubDescriptor hubDescriptor, Microsoft.AspNet.SignalR.IRequest request)
    {
        bool isHttps = request.Environment["owin.RequestScheme"].ToString().Equals("https", StringComparison.OrdinalIgnoreCase) ? true : false;
        bool internalPort = request.Environment["server.LocalPort"].ToString().Equals("2000") ? true : false;

        switch(hubDescriptor.Name)
        {
            // External Hubs
            case "masterHub":
            case "childHub":
                if (isHttps && !internalPort) return base.AuthorizeHubConnection(hubDescriptor, request);
                break;
             // Internal hubs
            case "workerInHub":
            case "workerOutHub":
                if (!isHttps && internalPort) return base.AuthorizeHubConnection(hubDescriptor, request);
                break;
            default:
                break;
        }
        return false;
    }
}

OTHER TIPS

A simple solution you can use roles of client to distinguish between to connections

    object GetAuthInfo()
    {
        var user = Context.User;
        return new
        {
            IsAuthenticated = user.Identity.IsAuthenticated,
            IsAdmin = user.IsInRole("Admin"),
            UserName = user.Identity.Name
        };
    }

also other options are fully described here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top