SockJS authenticate webuser with JWT

556 views
Skip to first unread message

Ronald van Raaphorst

unread,
Dec 7, 2015, 8:41:09 AM12/7/15
to vert.x
Ok, I might be doing nobody does or I might be missing something (vertx 3.1)

I was wondering if it's possible to authenticate a user using SockJS without having to have an authenticated user in a web session first.
The idea is that a previously given JWT is used once to authenticate a user for as long as that socket connection is open (So not send it on every socket request)
and use the permitted options/roles out of the box.

Normal usage is: Authenticate a user with credentials in say a http post. This results in a websession (defined by a session cookie) containing
the user. Next, a SockJS connection is established and upon upgrading the http connection to a socket connection,
the authenticated user is taken from the routingcontex/session and set as webuser for that socket connection.

Scenario:
Open a SockJS connection - No http request is executed before.
Require the first message to contain that token or otherwise close the session. 
(There's discussion on whether it's wise to send credentials/jwt along with the first socket request, see https://github.com/sockjs/sockjs-client/issues/196)
Use the token to authenticate the user and set that as the user for the socket for every subsequent call.
For every other socket call, intercept any inbound message and inject a reference to the socket session in the message header.
Any consumer retrieves this reference from the message header, uses it to retrieve the socket and the socket().user() and
can perform it's intended action based on the user's role.

(A message consumer could retrieve different record sets based on whether the user has an admin role, a user role or some other role).

It's AFAIK not possible to set the webuser anywhere from within the SockJS event bridge handler, is it?
If this is possible, is it possible to retrieve the socket's user from any message bus handler 
(In the bridge handler, inject a reference to the socket in the message header along these lines:https://groups.google.com/d/msg/vertx/rhINSChwl7s/TVoBd-FHlVQJ)

Paulo Lopes

unread,
Dec 7, 2015, 10:15:15 AM12/7/15
to vert.x
Currently you need to authenticate first and then open the sockjs so it gets the user form the session handler as in the example:

https://github.com/vert-x3/vertx-examples/blob/master/web-examples/src/main/java/io/vertx/example/web/angular_realtime/Server.java

If you want to skip the web auth then you need to have total control then when you create your SockJSHandler you need to use:

http://vertx.io/docs/apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandler.html#bridge-io.vertx.ext.web.handler.sockjs.BridgeOptions-io.vertx.core.Handler-

 bridge(BridgeOptions bridgeOptions,
                     Handler<BridgeEvent> bridgeEventHandler)

And then in your bridge event handler you can control if the token is present and perform the actions required deny/allow according to your rules...

Ronald van Raaphorst

unread,
Dec 7, 2015, 10:25:23 AM12/7/15
to vert.x
Thx, Paolo. Thx for the quick reply.

Currently you need to authenticate first and then open the sockjs so it gets the user form the session handler as in the example:

https://github.com/vert-x3/vertx-examples/blob/master/web-examples/src/main/java/io/vertx/example/web/angular_realtime/Server.java

If you want to skip the web auth then you need to have total control then when you create your SockJSHandler you need to use:

http://vertx.io/docs/apidocs/io/vertx/ext/web/handler/sockjs/SockJSHandler.html#bridge-io.vertx.ext.web.handler.sockjs.BridgeOptions-io.vertx.core.Handler-

 bridge(BridgeOptions bridgeOptions,
                     Handler<BridgeEvent> bridgeEventHandler)

And then in your bridge event handler you can control if the token is present and perform the actions required deny/allow according to your rules...


Yes, but you can't set the socket's user as it can only be set in the SockJSSession's constructor. As there's no websession, there's no session id and
thus the socket isn't put in any (shared) map to be retrieved from elsewhere in the application.

 
Reply all
Reply to author
Forward
0 new messages