-1

I'm using the latest version of SignalR from NET6. I have a JavaScript client in MVC 4 calling the hub. When I publish to Azure, I get a CORS error on the negotiation handshake. If I turn off the negotiation the CORS error goes away. Why does the negotiation call not use my CORS policy? What are the pros and cons for the negotiation?

Here's my JavaScript console:

enter image description here

Here's my NET6 API CORS policy:

builder.Services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
    builder.AllowAnyMethod().AllowAnyHeader().WithOrigins
    (
        //omitted
    ).AllowCredentials().SetIsOriginAllowed(o => true).WithMethods("GET", "POST");
}));

My client builder:

var connection = new signalR.HubConnectionBuilder()
    .withUrl(connectionUrl,
        {
            accessTokenFactory: () => {
                if (typeof bearerToken !== 'undefined') {
                    return bearerToken.getToken;
                }
            },
            skipNegotiation: true, //if I change this to false the error occurs
            transport: signalR.HttpTransportType.WebSockets,
        })
    .withAutomaticReconnect()
    .configureLogging(signalR.LogLevel.Information)
    .build();

skipNegotiation: true removes the error

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
GH DevOps
  • 305
  • 1
  • 11

2 Answers2

2

I found my issue. The SignalR Core JavaScript client will only connect with websockets if used in a .Net Framework app. All other protocols will fail. I tested with a NET 6 and Core 3.1 app and I was able to use Websockets and LongPolling. So if you're using an old .Net Framework app that's using a core client, limit the client to websockets only and skip the negotiation handshake:

.withUrl(connectionUrl,
    {
        accessTokenFactory: () => {
            if (typeof bearerToken !== 'undefined') {
                return bearerToken.getToken;
            }
        },
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets,
    })
GH DevOps
  • 305
  • 1
  • 11
  • this (skipNegotiation:true) solved the issue (localhost) on my Angular app using @microsoft/signalr@7.02 in aspnetcore app using "Microsoft.AspNetCore.SignalR.Common" Version="7.0.2". (havent verified if there are any issues this will lead to – JimiSweden Jan 22 '23 at 10:16
  • "WebSockets and CORS are not compatible " says Brennan on the signalR team : skipNegotiation will skip the HTTP negotiate that does transport fallback and will only run WebSockets. WebSockets and CORS are not compatible so you end up skipping CORS when using that. https://github.com/dotnet/aspnetcore/issues/4457#issuecomment-444738776 - – JimiSweden Jan 22 '23 at 10:20
1

skipNegotiation will skip the HTTP negotiate that does transport fallback and will only run WebSockets. WebSockets and CORS are not compatible so you end up skipping CORS when using that.

You can follow these github issue1,github issue2 to learn more skipNegotiation in signalr.

Xinran Shen
  • 8,416
  • 2
  • 3
  • 12