2

I'm working on a .NET 5 project implementing SignalR for use with an Angular 11 front-end, with OAuth2 authentication. The app is hosted on Kubernetes so I need to use skipNegotiation: true and transport: HttpTransportType.WebSockets to force the connection to establish itself on a single server behind my load balancer. This forces the SignalR library to send my access token as a query string parameter. After implementing I was getting a 404 response and it's taken me ages just to work out why: my access token is too long. If I send random characters as the access token up to a length of around 2035 characters, it works (well, it fails authentication obviously, but that's expected). If I send my full access token which is somewhere around 2500 characters long, it returns the 404 response.

I believe my implementation is fairly typical as it's just following example code so far:

Startup.cs:

// In ConfigureServices()
services.AddSignalR();

//In Configure()
app.UseEndpoints(endpoints => {
    endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapHub<MessageHub>("/message-hub");
});

MessageHub.cs:

public class MessageHub : Hub {
    public async Task EchoTest(string message) => await Clients.All.SendAsync("echo", message);

    public override Task OnConnectedAsync() {
        Debug.WriteLine("connected");
        return base.OnConnectedAsync();
    }
}

Client:

const connection = new HubConnectionBuilder()
  .withUrl('http://localhost:5001/message-hub', {
    skipNegotiation: true,
    transport: HttpTransportType.WebSockets,
    accessTokenFactory: () => {
      return 'MY_ACCESS_TOKEN'; // If 2036 characters or greater, 404 responses ensue
    }
  })
  .build()
  .start()
  .then(() => console.log('Connection started'))
  .catch(err => console.log('Error while starting connection: ' + err))

It's feasible to for me to reduce the length of the access token with a lot of refactoring of claim identifiers and etc. but that's a last resort. What I'm ideally after is a way to provide my current large access token as-is to SignalR without it breaking. Any suggestions would be appreciated.

wwarby
  • 1,873
  • 1
  • 21
  • 37

1 Answers1

2

The thing which throws 404 is an IIS request filtering. The following web.config fixed the issue for us

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxQueryString="5000"></requestLimits>
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>
Maxim Balaganskiy
  • 1,524
  • 13
  • 25
  • That wouldn't solve the problem for me because my app is running self-hosted in Kestrel on Linux, but I wonder if there is some equivalent configuration for Kestrel hosts. Cheers for the suggestion. I've moved on a bit now - I massively simplified permissions since this so my access_token is much smaller anyway, but I'll do a bit of reading and see if in principle I can solve the problem this way. – wwarby Nov 06 '21 at 05:02