Open Closed

Cannot make authorized SignalR Hub class work with Angular app #4248


User avatar
0
alexander.nikonov created
  • ABP Framework version: v5.1.2
  • UI type: Angular
  • DB provider: EF Core
  • Identity Server Separated

I have installed AbpAspNetCoreSignalRModule into HttpApi.Host project and put it into Module dependencies. I also used the following setup:

    Configure<AbpSignalROptions>(options =>
    {
        options.Hubs.AddOrUpdate(
            typeof(NotificationHub),
            config =>
            {
                config.RoutePattern = "/signalr-hubs/notification";
                config.ConfigureActions.Add(hubOptions =>
                {
                    //Additional options
                    hubOptions.LongPolling.PollTimeout = TimeSpan.FromSeconds(30);
                });
            }
        );
    });

The code above is followed by ConfigureSwagger setup. Nevertheless, I don't see signalr-hubs/notification endpoint at my Swagger page. I even installed Swagger extension from Nuget, but I still can't see this endpoint. WHY? This is question #1.

Question #2. Why Angular app does not work with SignalR?

    @Injectable({
      providedIn: 'root'
    })
    export class SignalRService {
    
      private hubConnection: signalR.HubConnection
        public startConnection = () => {
          this.hubConnection = new signalR.HubConnectionBuilder()
            .withUrl
            (
              `${environment.apis['default'].url}/signalr-hubs/notification`,
              { skipNegotiation: true, transport: signalR.HttpTransportType.WebSockets }
            )
            .build();
          this.hubConnection
            .start()
            .then(() => console.log('Connection started'))
            .catch(err => console.log('Error while starting connection: ' + err))
        }
        
        public addNotificationListener = () => {
          this.hubConnection.on('notificationreceived', (data) => {
            console.log(data);
          });
        }
    }

The error is:

Probably something is not fully correct with my Ocelot gateway settings, but I am even not sure the Hub endpoint is available. How do I check this??

    {
        "DownstreamPathTemplate": "/signalr-hubs/notification",
        "DownstreamScheme": "wss",
        "DownstreamHostAndPorts": [
            {
                "Host": "localhost",
                "Port": 44328
            }
        ],
        "UpstreamPathTemplate": "/centraltool/signalr-hubs/notification",
        "UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ],
        "Key": "centraltool-signalr"
    },

Anticipating your question: no, I cannot send the project. And we have no time trying to make things work in the test project: our setup is more complex and it would not help us in any way if we find out the test sample DOES work. Please help us to understand, what is wrong here. Step by step.

Thank you.


4 Answer(s)
  • User Avatar
    0
    alexander.nikonov created

    UPDATE.

    It started to work after I removed [Authorize] attribute from my Hub class. Does it mean that currently SignalR is working without authentication? I know that SignalR does not work with headers, but I don't want to pass token via URL. Should I ever worry about that, if my SignalRService code works within AppComponent which is available only for authorized user?

    Probably you can suggest another approach to be on safe side? In addition to using tokens, I used to create token cookie in my HttpApi.Host project middleware and added it later on to each request like this (for instance, for Hangfire dashboard page), but at some point cookie functionality got broken - probably after introducing Ocelot gateway, not sure...

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    1. I don't see signalr-hubs/notification endpoint at my Swagger page.

    Only HTTP endpoints can be seen on the swagger page.

    1. It started to work after I removed [Authorize] attribute from my Hub class. but I don't want to pass token via URL.

    You should not remove Authorize, We recommend that you pass the access token to complete the authentication.

    https://learn.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-7.0#built-in-jwt-authentication https://ocelot.readthedocs.io/en/latest/features/websockets.html

  • User Avatar
    0
    alexander.nikonov created

    You should not remove Authorize, We recommend that you pass the access token to complete the authentication.

    https://learn.microsoft.com/en-us/aspnet/core/signalr/authn-and-authz?view=aspnetcore-7.0#built-in-jwt-authentication https://ocelot.readthedocs.io/en/latest/features/websockets.html

    I've already seen and used it before. As I said, passing token in URL doesn't seem very prominent. But this confuses me at Ocelot at NOT SUPPORTED section: "Authentication - If anyone requests it we might be able to do something with basic authentication."

    So what is the underline here? Does authentication for Ocelot + SignalR does not suggest another way of request authentication besides passing token via URL?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    I think it is the current practice to pass the token in the URL.

    Related topic: https://github.com/abpframework/abp/issues/5239

Made with ❤️ on ABP v9.1.0-preview. Updated on December 13, 2024, 06:09