Struggling with implementing automatic Windows Authentication on my signalr server, I've managed to make it work with a C# client but not with the javascript web client.
In my setup, I have a C# server providing access to a SignalR API (Hub) and two versions of that server: one standalone self-host and one included in an ASP web solution, both sharing the same Owin Startup code.
I have two clients as well: a standalone C# client where setting Credentials
property of IHubConnection
works fine, and a javascript signalr client generated by my ASP server.
However, when trying to connect using the signalr javascript client, I get an Unauthorized Access response from my ASP server.
Despite extensive research, I couldn't find any documentation on how to set the credentials in the javascript equivalent of HubConnection
.
The setup that works:
The Working Setup:
public class ServerStartup
{
public virtual HubConfiguration HubConfiguration => new HubConfiguration
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = false
};
public void Configuration(IAppBuilder app)
{
ConfigureSignalR(app);
ConfigureAuth(app);
}
private void ConfigureSignalR(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
try
{
app.MapSignalR("/endpoint", HubConfiguration);
}
catch (InvalidOperationException)
{
// raised when the system's performance counter is not available
}
}
private void ConfigureAuth(IAppBuilder app)
{
object listener;
if (app.Properties.TryGetValue(typeof(HttpListener).FullName, out listener))
{
((HttpListener)listener).AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;
}
}
}
The Client Code:
var connection = new ClientConnection($"http://localhost:{Port}/endpoint", useDefaultUrl: false)
{
TransportConnectTimeout = TimeSpan.FromSeconds(50),
Credentials = CredentialCache.DefaultCredentials
};
With this setup, Context.User
contains the correct IIdentity
information from the local windows user currently connected.
The failing setup:
EDIT: It actually works, see my answer below.
The ASP Startup Class:
[assembly: OwinStartup(typeof(Dashboard.Startup))]
namespace Dashboard
{
public class Startup : ServerStartup
{
public override HubConfiguration HubConfiguration => new HubConfiguration
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true,
EnableJSONP = true
};
}
}
The Javascript Client:
$.connection.hub.start()
.done(function() {
$.connection.MyHubName.server.myApiMethod(null)
.done(function(result) {
// success
})
.fail(function(error) {
console.log(error);
options.error(error);
});
})
.fail(function(error) {
console.log(error);
options.error(error);
});
Trying to figure out how to pass windows credentials to the SignalR API through the javascript client has been a challenge for me. My goal is to automatically log in anyone from my local internal network with their Windows Credentials when they visit the ASP website, so that I can identify them from my SignalR Hub.
If you have any ideas on how to implement this, please share as I have already exhaustively read through all the SignalR documentation multiple times.