3

SignalR gives me 404 when trying to connect for some users. URLs are the same except for access_token.

It is stable reproducible per user (I mean that some users are stable OK, some users are stable 404).

access_token parsed jwt diff (left is OK user, right gets 404): access_token parsed jwt diff


I did a trace level of logs and have next: For the OK user: TRACE console.log for OK user

For the user that gets 404: TRACE console.log for 404 user

Note: URLs under black squares are the same.


Front End is Angular 9 with package "@microsoft/signalr": "^3.1.8", and here's the code that builds the connection:

  private buildHub(): HubConnection {
    console.log(this.authService.accessToken);
    let builder = new HubConnectionBuilder()
                      .withAutomaticReconnect()
                      .configureLogging(LogLevel.Information)
                      .withUrl('ws/notificationHub', {
                          accessTokenFactory: () => this.authService.accessToken
                        });

    if (this.debugMode) {
      builder = builder.configureLogging(LogLevel.Trace);
    }

    return builder.build();
  }

Backend is using next code in Startup for configuring signalR hub:

In public void ConfigureServices(IServiceCollection services):

services.AddSignalR()
            .AddJsonProtocol(options =>
            {
                options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
            });

In public void Configure(IApplicationBuilder app, IHostingEnvironment env):

app.UseSignalR(route =>
            {
                route.MapHub<NotificationHub>("/ws/notificationHub");
            });

Also we use custom authentication, so we have Authorize attribute for the Hub class:

    [Authorize]
    public class NotificationHub: Hub<INotificationHubClient>

and this code in public void ConfigureServices(IServiceCollection services):

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.Authority = identityServerSettings.Url;
                    options.Audience = identityServerSettings.ApiScopeName;
                    options.RequireHttpsMetadata = identityServerSettings.RequireHttpsMetadata;

                    options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
                    {
                        OnMessageReceived = context =>
                        {
                            var accessToken = context.Request.Query["access_token"];
                            var path = context.HttpContext.Request.Path;
                            if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/ws"))
                            {
                                context.Token = accessToken;
                            }
                            return Task.CompletedTask;
                        }
                    };
                });

Unfortunately, I don't have the full access to the environment where it is reproducible, but I can request to see any settings or try to make some changes.

What else can I try to troubleshoot the issue?


UPDATE: negotiate is fine for both users.

A. Yushchenko
  • 105
  • 2
  • 5

1 Answers1

1

I had this issue recently, after the size of my JWT increased. I found that in my case the 404 error was being thrown by IIS because the query string exceeded the limit of 2048. After increasing the query string max length, my issue was resolved.

Sparviero
  • 26
  • 1