I've been trying to implement automatic Windows Authentication on my signalr server, and only got it working with a C# client, but not with the javascript web client.
To give you some context: I have a C# server that provides an access to a SignalR API (Hub), and broadcasts messages to its connected clients. I have two versions of that server, one standalone self-host and one included in an ASP web solution, that share the same Owin Startup code.
I also got two clients : one standalone C# one, in which I can create an IHubConnection
and set its Credentials
property to CredentialCache.DefaultCredentials
(which works fine), and also the javascript signalr client (js hub proxy) generated by my ASP server.
I'm facing an Unauthorized Access response from my ASP server when trying to connect using the signalr javascript client.
I've been struggling to find any documentation about a javascript equivalent to setting the Credentials
property of my HubConnection
.
The working setup:
The Owin Startup class:
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 HubConnection:
var connection = new ClientConnection($"http://localhost:{Port}/endpoint", useDefaultUrl: false)
{
TransportConnectTimeout = TimeSpan.FromSeconds(50),
Credentials = CredentialCache.DefaultCredentials
};
I get the expected result that my Context.User
contains the right IIdentity
filled with information from the local windows user currently connected.
The failing setup:
EDIT: It actually works, see my answer below.
My 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);
});
I don't know how I could tweak my javascript client so that the windows credentials are passed to the SignalR API.
The feature I want to implement is that anyone from my local internal network is automatically logged in with his/her Windows Credentials when getting to the ASP website from a web browser, so that I can identify them from my SignalR Hub.
Any idea about how I can implement that? (I already read all the signalr documentation... at least twice...)