Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wss stopped working, cannot figure out the reason #1664

Closed
alexandis opened this issue Jun 3, 2023 · 10 comments
Closed

wss stopped working, cannot figure out the reason #1664

alexandis opened this issue Jun 3, 2023 · 10 comments
Assignees
Labels
waiting Waiting for answer to question or feedback from issue raiser Websockets Ocelot feature: Websockets wontfix No plan to include this issue in the Ocelot core functionality.

Comments

@alexandis
Copy link

alexandis commented Jun 3, 2023

We used Ocelot 18.0 + SignalR on localhost environment, it was Angular 13.x.
We use self-signed certificates and everything worked smoothly with this simple configuration:
image

We upgraded to Angular 15 (the corresponding version of SignalR NPM has been updated accordingly) - I'm writing this just to emphasize there was no other relevant changes that come on my mind. And it does not work now. I cannot figure out why and probably you would give me some hint?
image
Could it be somehow related to Ocelot or I should exclude it from suspicion list?

@raman-m
Copy link
Member

raman-m commented Jun 3, 2023

Hi Alexandis!
Thanks for your interest in Ocelot!

A lot of people tries to route wss-protocol traffic via Ocelot gateway, but they failed! 🤣
Here are other issues related to WSS:

Are you sure that Ocelot v18 + WSS SignalR setup is working?
Officially Ocelot does not support WSS protocol at all. You will find nothing related to wss-protocol in documentation!
More about: Websockets

I would recommend you to connect to the service directly without Ocelot.

Finally,
Could you let us know that your direct connection to the service is working please?
Any logs, screenshots are welcome!
After that we will continue discussion...

@raman-m raman-m added question Initially seen a question could become a new feature or bug or closed ;) waiting Waiting for answer to question or feedback from issue raiser Websockets Ocelot feature: Websockets labels Jun 3, 2023
@raman-m
Copy link
Member

raman-m commented Jun 3, 2023

Aha, and one more update!
We need to keep in mind always that if Microsoft has provided new version of .NET, for instance .NET 6 to 7 release, then with high probability we have breaking changes and some new features in the System.Net namespace. Also the System.Net.WebSockets namespace can have new changes. For example the ClientWebSocket class can have significant upgrade to support latest changes of SignalR.
So, Ocelot has no injectable packages to vary WebSockets and SignalR between .NET versions.
This is the major problem of Ocelot for now!

So, when you said:

cannot figure out the reason

I would say that Websockets feature is broken during .NET version upgrade. See above ☝️

@alexandis
Copy link
Author

Answering your first question - yes, suprisingly the shown configuration allowed us to befriend wss and Ocelot 18, working on localhost without hitch.
And then - thank you for the last comment: I made a direct connection and ensured the error is the same. Which probably means that "Websockets feature is broken during .NET version upgrade"... :(

@raman-m
Copy link
Member

raman-m commented Jun 5, 2023

I'm glad that my explanations helped you!
Yes, rolling back to Ocelot v18 is good idea to get wss-traffic being routed.
But I'm surprised also, that old Ocelot supports wss proto.

Who knows maybe I will reopen this issue soon, because it has interesting specification Ocelot v18 + SignalR npm package for Angular.
Are you sure that Angular 15 and SignalR NPM for Node.js are compatible? What exact npm are you using?

Finally, the team and me, are interested in support of latest release of Ocelot (v19, .NET 7 release).
I'm afraid we can accept bugs for latest version only. Old Ocelot packages/releases are not supported by our team!
Could you upgrade the gateway solution to v19.0.2 release please?
And let us know the user scenario results once again please!

@alexandis
Copy link
Author

alexandis commented Jun 15, 2023

I want to finally clarify what actually happened in my case.
The reason of my error was actually irrelevant to Ocelot. It was related to the overflown JWT token: too much data was packed into it and the token was actually invalid.

But the mechanism with adding token to URL for authenticating wss request really works with Ocelot provided the configuration above. You just need to add the following code into HTTP request middleware:

               options.Events = new JwtBearerEvents
               {
                   OnMessageReceived = context =>
                   {
                       if (context.HttpContext.Request.Path.StartsWithSegments("/signalr-hubs/notification"))
                       {
                           if (context.Request.Query.TryGetValue("access_token", out StringValues accessToken))
                           {
                               context.Token = accessToken.First(); //authenticating WSS request
                           }
                       }
                       return Task.CompletedTask;
                   }
               };

The question of security having token in URL is another matter and needs to be discussed separately. However, there is no other way to authenticate wss request in another way, as far as I know...

@raman-m raman-m added wontfix No plan to include this issue in the Ocelot core functionality. and removed question Initially seen a question could become a new feature or bug or closed ;) waiting Waiting for answer to question or feedback from issue raiser labels Jun 16, 2023
@raman-m
Copy link
Member

raman-m commented Jun 16, 2023

Yeah, yeah!
Ocelot can route requests even with invalid tokens in query params! 🤣

Also, what is the problem to move auth-token to headers or even to body?

If you have an intention to come back to us with well-defined WSS feature request in future, we will accept it with pleasure.

@alexandis
Copy link
Author

From what I've heard lately, wss does not support passing token via header or body - only URL.

@raman-m
Copy link
Member

raman-m commented Jun 20, 2023

Alexandis,

    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            if (context.HttpContext.Request.Path.StartsWithSegments("/signalr-hubs/notification"))
            {
                if (context.Request.Query.TryGetValue("access_token", out StringValues accessToken))
                {
                    context.Token = accessToken.First(); //authenticating WSS request
                }
            }
            return Task.CompletedTask;
        }
    };

I've searched for the source code in Ocelot and I didn't find something similar.
I guess this coding recipe can be useful in Ocelot...
What issue have you resolved by this code?

It looks like you forgot to register authentication, authorization services in these Ocelot features:

Do you think we need to develop Websockets somehow?
My understanding is that in your coding recipe you forward auth-token from query params to be authorized by downstream WSS service, right?
I need just understand is it implemented in Ocelot or not?

Is your user case covered by JWT Tokens authenticationProviderKey and AddJwtBearer method?

@raman-m raman-m added the waiting Waiting for answer to question or feedback from issue raiser label Jun 20, 2023
@alexandis
Copy link
Author

alexandis commented Jun 20, 2023

@raman-m thank you - we indeed do not use these extensive Ocelot configuration options. Actually, I was not the one in the team making use of Ocelot in our system, so I don't have much detail about it. Probably these configuration options might come in handy for us if we get the issue while publishing our solution in test Azure environment (where we do not have SSL certificate and will need to use that "ignore" thing for accepting self-made certificates and so on)... I do not know in advance actually, sorry.

As to my piece of the code - it is to authorize the wss request with incoming URL token on the site where SignalR hub actually resides on. It is not connected to Ocelot, but probably might be useful for someone if he meets the issues with SignalR functioning...

@raman-m
Copy link
Member

raman-m commented Jun 22, 2023

Aha...
Could you read and review the Websockets chapter please?

After my review I see that Websockets vs SignalR don't support authentication & authorization at all.
Look into this section: Websockets | Not Supported
The points 11, 12 say that authentication and authorization are not supported.
I guess it is true. But I need to dive into the source code deeply to understand current situation...

If points 11, 12 are still actual then it means we can provide some basic authorization support for downstream services via JWT token forwarding like it is implemented in your coding recipe. But for sure this recipe must be generic without any hardcoded options and/or settings.

What do you thing?

Also, could you upload your solution to GitHub please? You can remove real hosts for security, just replace them by localhost.
Pay attention that some real and useful solutions can be added to Ocelot as web app sample to folder: samples

Also sample project/solution can show us the possible approach and design, and we could enhance old feature or develop new feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting Waiting for answer to question or feedback from issue raiser Websockets Ocelot feature: Websockets wontfix No plan to include this issue in the Ocelot core functionality.
Projects
None yet
Development

No branches or pull requests

2 participants