I'm trying to get signalR to work with a .net core 2.2 application. I need to connect to it from an angular front end. I have another app that is seemingly configured the same way that already has signalR working. When I connect to the other app from the angular it works but if I try to connect to the original app I get a 401 error. the code involving signalR looks identical as far as I can tell.
We use windows intranet authentication. I don't have access to any of the devs who set this up originally but it's all in our windows intranet site and we login via an alert popup that I put my intranet info into.
Here's relevant code in startup.cs configure services
services.AddCors();
services.AddSignalR();
Here's in sertup.cs configure
var origins = Configuration.GetValue<string>("apiAllowedOrigins").Split(',');
app.UseCors(builder =>
builder.WithOrigins(origins)
.AllowAnyMethod()
.AllowCredentials()
.AllowAnyHeader()
);
app.UseAuthentication();
app.UseSignalR(routes =>
{
routes.MapHub<IbjaHub>("/ibjahub");
});
Here's ibjahub
using Microsoft.AspNetCore.SignalR;
namespace CapitalJobs.SignalR
{
public class IbjaHub : Hub
{
}
}
Here's the angular code connecting to the hub
this._ibjaService
.getSignalRHub()
.pipe(
tap(hd => {
const hubConnection = new signalR.HubConnectionBuilder()
.withUrl(hd.hubURL)
.build();
hubConnection
.start()
.then(() => {
console.log('SignalR Connection started');
})
.catch(err => {
this._toaster.pop({
type: 'error',
title: 'Connection Lost',
body: `Connection to server lost, and attempts to reconnect failed. Please refresh the page.`,
timeout: 0,
bodyOutputType: BodyOutputType.TrustedHtml
});
console.error(err);
});
hubConnection.on(
'todo: replace this with what its going to say',
data => {
if (data.username !== this._config.appMenu.userName) {
return;
}
//todo parse the data about e1
}
);
hubConnection.onclose((error?: Error) => {
if (error) {
console.error(error.message);
window.setTimeout(() => {
hubConnection
.start()
.then(() => {})
.catch(err => {
this._toaster.pop({
type: 'error',
title: 'Connection Lost',
body: `Connection to server lost, and attempts to reconnect failed. Please refresh the page.`,
timeout: 0,
bodyOutputType: BodyOutputType.TrustedHtml
});
console.error(err);
})
.then(() => {
this._toaster.pop({
type: 'warning',
title: 'Connection Lost',
body: `Connection to server was lost, but was successfully reconnected. Some messages may have been lost. Please refresh the page if issues continue.`,
timeout: 0,
showCloseButton: true,
bodyOutputType: BodyOutputType.TrustedHtml
});
});
}, 2000);
}
});
})
)
.subscribe();
}
I used the same code to connect to the working api vs the one that doesn't work. Here's a side by side screen shot of the results of the options request.
options request from calls to both apis
I've gone through many solutions on stack overflow as well as microsoft forums.
I tried adding a kestrel server line to program.cs.
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((builderContext, config) =>
{
})
.UseStartup<Startup>()
.ConfigureKestrel((context, options) =>{}) // this line
.UseNLog()
.Build();
}
I've added forwarding the tokens in start up both shown below.
services.AddAuthentication(IISDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "<issuer removed>",
ValidAudience = "<audience removed>",
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["CapitalJobs:JWTSigningKey"]))
};