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

Support setting HTTP headers for WebSocket connection #305

Open
wolfman42 opened this issue Jan 4, 2024 · 5 comments
Open

Support setting HTTP headers for WebSocket connection #305

wolfman42 opened this issue Jan 4, 2024 · 5 comments
Assignees
Labels
enhancement New feature or request

Comments

@wolfman42
Copy link

Proposed change

Support setting of (additional) HTTP headers for WebSocket connection. This could be a new part of NatsOpts class. Useful for providing an Authorization header. Perhaps along the following lines:

        var opts = new NatsOpts {
            Url = $"wss://localhost:8181"
        };
        opts.SetWebSocketHeader("authorization", $"Bearer {accessToken}");
        await using var nats = new NatsConnection(opts);
        await nats.PingAsync();

OnConnectingAsync callback should allow updating the headers, so that an authorization token could be refreshed.

Use case

JWT based authorization outside of NATS server.

Contribution

yes, interested.

@caleblloyd
Copy link
Contributor

I don't think that WebSockets support HTTP Headers. I've been frustrated by this before 😄

https://stackoverflow.com/a/4361358

SignalR Core uses a query string parameter to transmit bearer tokens over websockets

@wolfman42
Copy link
Author

wolfman42 commented Jan 4, 2024

I don't think that WebSockets support HTTP Headers. I've been frustrated by this before 😄

https://stackoverflow.com/a/4361358

SignalR Core uses a query string parameter to transmit bearer tokens over websockets

WebSockets in C# (and most other languages / frameworks) do support HTTP headers. The only situation when it's not supported (AFAIK) is when you try to connect a WebSocket from a browser application.

Here's a C# example:

            using (var socket = new ClientWebSocket())
                try
                {
                    socket.Options.SetRequestHeader("authorization", $"Bearer {accessToken}");
                    await socket.ConnectAsync(new Uri($"wss://localhost:8181"), CancellationToken.None);

                    await Send(socket, "data");
                    if (!await Receive(socket)) return;

                }
                catch (Exception ex)
                {
                    Console.WriteLine($"ERROR - {ex.Message}");
                    return;
                }

@caleblloyd
Copy link
Contributor

caleblloyd commented Jan 4, 2024

Good to know. Maybe we could have a callback in NatsOpts:

Func<Uri, ValueTask<ClientWebSocketOptions>>? ConfigureWebSocketOpts

Where the Uri argument is the URI of the NATS Server we are attempting to connect to

@mtmk mtmk added the enhancement New feature or request label Jan 5, 2024
@adamreed90
Copy link

👍 I could see this being extremely useful with Blazor WebAssembly, specifically with being able to securely emit events from the frontend without the need for SignalR

@caleblloyd
Copy link
Contributor

I think that Blazor WebAssembly running in the browser will use the Browser's websocket implementation, which doesn't support headers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants