Authentication for websocket browser clients

2,978 views
Skip to first unread message

Che Yonggang

unread,
Jan 28, 2019, 9:57:46 AM1/28/19
to vert.x
In our Vertx websocket server, we are struggling to find a good method to authenticate clients from browsers.

For our non-browsers clients, we authenticate based on the request header of Basic Authentication.
But there is no way they specify the Authentication Header in javascript from browser.

they use Sec-WebSocket-Protocol to pass token to server.
Not sure whether it's a good idea to do this, does vertx support this kind of operation?

Julien Viet

unread,
Jan 29, 2019, 3:33:37 AM1/29/19
to ve...@googlegroups.com
Hi,

I don't think we don't support it (yet).

Julien

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/5a4c52c1-11ad-4d64-a0cb-bd1bf3b27c57%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Paulo Lopes

unread,
Jan 30, 2019, 5:49:02 AM1/30/19
to vert.x
The WebSocket web client wasn't designed with AuthN/Z in mind. So you can't set headers directly, there are alternatives though:

If you use a url like: wss://user:password@server/path

This will produce a header:

Authorization: basic base64(user:password)

So you should only use it with TLS.

A second alternative is:

wss://server/path?access_token=oauth2token

BUT this is flaky as servers can log the request url and tokens be leaked.

The approach k8s is using is a hack, it is reusing a header that was meant for something else and other projects do the same using their own format, so I don't believe we should standardize on it.


And the divide goes even further, for example heroku recommends to handle AuthNZ at the message level. Auth0 did the same but the link is now broken...

Che Yonggang

unread,
Jan 30, 2019, 10:09:09 AM1/30/19
to vert.x
Thanks Paulo.

Unfortunately the major browsers (Chrome, Firefox) deprecated the usage of wss://user:password@server/path to produce Basic Authorization header a few years ago.

The heroku link is interesting, but since we are targeting internal users of websocket, we don't want this authentication thing too complicated. Actually we are more about user authorization check, maybe just some token check is enough, like k8s did.

Paulo Lopes

unread,
Jan 30, 2019, 1:53:35 PM1/30/19
to vert.x
I understand, what I dislike about it is for example it will mess up with user that use the header properly, for example graphql. GRaphQL uses the header for subscriptions so it switches from RPC style to a subscription style:


If we now start adding weird header values I think we might be opening a can of worms ...

Chris Miller

unread,
Aug 16, 2019, 9:36:19 AM8/16/19
to vert.x
I'm trying to achieve the same thing as the original poster. I want to use sec-websocket-protocol to pass a JWT auth token through when creating a websocket connection (as per the discussion here https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api). I want to do this so I can use our existing Pac4J authentication SecurityHandler rather than implement an additional authentication protocol just for websockets. This would help keep things simple and makes the security less fragile.

Note that I'm not expecting Vertx to provide this out of the box, just allow it to be possible by rolling my own handlers and so on. I was hoping to do this as follows:

1) Have a handler that replaces any "sec-websocket-protocol" request header is sees with an appropriate "authorization" header instead (as required by step #2).
2) Have the SecurityHandler validate/reject the token in the "authorization" header, exactly the same as for a normal HTTP request.
3) Upgrade or reject the websocket upgrade depending on whether the security check was successful.
4) Have a handler that writes the auth token back into the "sec-websocket-protocol" response header (to maintain compliance with the websocket spec).

I have some of the above parts working but am having trouble getting it working as a whole. I know the websocket handling in Vertx/Netty tries to deal with the "sec-websocket-protocol" header automatically which might get in the way, and I'm not sure whether context.addHeadersEndHandler() still gets called after a websocket.accept(). Before I spend too much time fighting issues like these, is the above approach a valid one or should I just give up and roll my own websocket auth protocol/messaging instead?

Many thanks,
Chris

Ronald van Raaphorst

unread,
Dec 22, 2020, 7:47:00 AM12/22/20
to vert.x
Hi Chris,

I suppose you did already fix the issue, but i ran across the same issue too. See https://groups.google.com/g/vertx/c/FticB_8WL3I

Ronald
Reply all
Reply to author
Forward
0 new messages