Websocket & authentication

370 views
Skip to first unread message

Ronald van Raaphorst

unread,
Dec 21, 2020, 11:04:30 AM12/21/20
to vert.x
Hi all,

Congrats on the 4.0.0 release, we're excited to move to this release!

Unfortunately, we're having trouble connecting the websockets:
If there's a route before the sockJs route that has an async call, the sockjs handler is not called upon the upgrade call.
If I comment out the timer (ie, the red lines), the exact same code otherwise works fine
and the connection is established.

val mainRouter = Router.router(vertx)

mainRouter.route(HttpMethod.GET, "/eventbus/*")
  .handler { context ->
     vertx.setTimer(1) {         // This doesn't work (async)
         context.request().headers().forEach { logger.info(it.key + ":" + it.value) }
         context.setUser(User("""{ "id": 2, "role": "ADMIN" }"""))   
         context.next()
    }
}

mainRouter.mountSubRouter("/eventbus",
   sockJsRouter.bridge(bridgeOptions, bridgeEventHandler))

Without the timer, the bridgeEventHandler is called with the proper events,
with the timer, the connection is not established.

Reason we do this is that we have legacy authentication code:
The upgrade call contains a JWT token in a (https) cookie that can be converted to a User instance and put in the context.
The actual call is calling a authentication handler.

These are the headers for the upgrade call:

GET http://localhost:8080/eventbus/979/xpx1vcuw/websocket
Host:localhost:8080
Connection:Upgrade
Pragma:no-cache
Cache-Control:no-cache
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Upgrade:websocket
Origin:http://localhost:4200
Sec-WebSocket-Version:13
Accept-Encoding:gzip, deflate, br
Accept-Language:nl,en-GB;q=0.9,en-US;q=0.8,en;q=0.7
Cookie:accessToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MiwicmVtZW1iZXJNZSI6ZmFsc2UsImlhdCI6MTYwODU2NTczMX0.TAR_DJuJDJMNCDzhTFO49U-GdP3yLDjOT2tyBuMLroM
Sec-WebSocket-Key:kHRbNdueXVS442HY5rYSww==
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits

I can't see any other way and this has worked fine for several years.

Ronald


Ronald van Raaphorst

unread,
Dec 22, 2020, 7:44:49 AM12/22/20
to vert.x
For clarity, we're trying to get this to work in 4.0.0 and it seems to work now if the context.request().pause() is added:

val eventBusRouter = Router.router(vertx)
eventBusRouter.route("/*").handler { context ->
    context.request().pause()    
    ourAuthenticationHandler.handleSocket(context)   // reads JWT cookie  in runs async, calls context.next()
}
eventBusRouter.mountSubRouter("/", sockJsRouter.bridge(bridgeOptions, bridgeEventHandler))

mainRouter.mountSubRouter("/eventbus", eventBusRouter)

Ronald


Julien Viet

unread,
Dec 26, 2020, 7:30:43 AM12/26/20
to vert.x
yes, the main reason is that now upgrading a WebSocket is asynchronous because it might fail and the WebSocket requires an handshake.

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.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/ff1a9315-8ca2-4288-ac96-62d7d9488d20n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages