quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.79k stars 2.68k forks source link

quarkus-websockets-next connecting from browser with JWT #42824

Open rasmushaglund opened 2 months ago

rasmushaglund commented 2 months ago

Description

From what I understand the RFC6455 WebSockets specification allows for token-based auth using request headers, but in the client Javascript WebSocket implementation it's not possible to send authorization headers.

I have a setup with using quarkus-websockets-next together with KeyCloak and would need to authenticate using the token retrieved by KeyCloak via a Javascript WebSocket.

Implementation ideas

I've seen multiple suggestions on how this limitation is bypassed but most of them seem to involve setting the token in the url, for example: ws://${token}@localhost/ws or ws://localhost/ws?token=${token}.

Is there a way to solve this today, or is this something that would need to be added to the extension?

Thank you, and thank you for all the good work you do on this project, it's much appreciated!

quarkus-bot[bot] commented 2 months ago

/cc @sberyozkin (jwt)

sberyozkin commented 2 months ago

@rasmushaglund Hi, my understanding that to make it work from Java Script, you'd need a subprotocol header to get the token available at the upgrade time stick around, I'm planning to work on a demo as part of the quarkus-langchain4j project to clarify some of these details for myself. CC @mkouba, AFAIK, it is not really in scope for websockets-next as such, users need to customize the protocol to get the token flowing, right ? I've seen a few example over the last couple of years but never properly focused, I'll need to focus on it asap...

rasmushaglund commented 2 months ago

Thank you @sberyozkin! Yeah, at least it would be super helpful with some simple example for how this can be done, since I guess that it might be a pretty common use case to use Websockets with authentication through Javascript.

I have very limiting knowledge of how Websockets work, but I'll give it a shot based on your explanation.

Thanks!

mkouba commented 2 months ago

AFAIK, it is not really in scope for websockets-next as such, users need to customize the protocol to get the token flowing, right ? I've seen a few example over the last couple of years but never properly focused, I'll need to focus on it asap...

I think that I saw workarounds using the query params and even abusing the Sec-WebSocket-Protocol header. Both can be inspected in a server endpoint callback method using the HandshakeRequest. You will likely need to modify the headers of the HTTP upgrade request. The io.quarkus.websockets.next.HttpUpgradeCheck API may come in handy.

I'm not sure what the correct solution is :shrug:.

CC @cescoffier

sberyozkin commented 2 months ago

Thanks @mkouba, I'll have to figure it all out with https://github.com/quarkiverse/quarkus-langchain4j/issues/609 :-)

Niavana97 commented 2 months ago

I use "token" URL parameters and HttpUpgradeCheck to verify user identity, but I don't know how to add the user to the SecurityContext.