SockJS inbound permitted question

81 views
Skip to first unread message

Tomek Widanka

unread,
Jun 11, 2015, 2:56:29 AM6/11/15
to ve...@googlegroups.com
Hi,

Lets consider the following scenario:

I have an eventbus message publisher, publishing messages to an address (ie. "address.TOKEN", where TOKEN is generated on user auth).
I'd like to secure this communication channel, as only a certain logged in user can access it, so in fact I'd like to drop register request based on authenticated user.

As for now the only thing that I can think of is:
1) setting inboundPermitted on sockjs to allow only logged users in;
2) creating sockjs bridge handler that would check, whether logged user is allowed to register as an "address.TOKEN" message consumer based on logged user;

Is there a better way to do it, or what I'm thinking of is the best solution?

Tom

Paulo Lopes

unread,
Jun 12, 2015, 4:09:57 AM6/12/15
to ve...@googlegroups.com
Hi Tom

What you're suggesting is correct, if you want to have a look at an example that does exactly that check it here:

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

So this is a port of the old vert.x 2 angular demo. What it does is:

* create a bridge
* protect the bridge with a auth provider by asserting that the context has a user (this is all you need if you want only authentication)
* further protect a bridge inbound with a specific "auhorisation" (say that you want to protect handlers based on roles) (from your description this is not really needed for you)

Cheers,
Paulo

Ian Andrews

unread,
Jun 12, 2015, 9:59:06 AM6/12/15
to ve...@googlegroups.com
As far as I can determine, it looks like the example shows how you can restrict the entire event bus to only connections that have a current login session, which definitely addresses question 1.  Unless I'm stupid (which is certainly possible) I didn't see anything to address question 2.

I'm actually quite interested in this topic.  I've been experimenting with using Vert.x in web apps for a while now but haven't ever taken on the auth portion.  From my quick research, I think you can solve question 2 by changing his example to be something like this:

Turn line 109 in Server.java to this:

SockJSHandler sockJSHandler = SockJSHandler.create(vertx);

sockJSHandler.bridge(options, event -> {
   
String address = event.rawMessage().getString("address");

   String token = address.replace("address.", "");

   User user = event.socket().webUser();

   user.isAuthorised(token, result -> {

     if (result.failed()) {

       event.fail("Failed to determine if user is authorized");

       return;

     }

     if (result.result()) {

       event.complete(true);

     } else {

       event.complete(false);

     }

   });

});

router.route("/eventbus/*").handler(sockJSHandler);


This should let you make a decision to let the message through the event bus based on the token.  The other interesting thing that this allows you to do is inject the username or other user information into the message itself or the message headers by interacting with the rawMessage.

Paulo, did everything I write sound correct?  I haven't actually done this before :-).

Paulo Lopes

unread,
Jun 12, 2015, 10:16:30 AM6/12/15
to ve...@googlegroups.com
No, you're not stupid :) and you're right it restricts the bus only to authenticated connections, Since we are at a point of releasing 3.0 if you need both public and authenticated bridges the only solution you have right now is to have 2 bridges or implement the authentication yourself by adding some property to the messages you're sending over. Which is what you're described in your example.

However your example has a problem which is not your fault. The socket connection is open at a given point in time if at that point it was open without a authenticated user then the line:

User user = event.socket().webUser();

Will always be null, and if the socket is open after authentication the it won't be null, this is because socket connections are persistent so the base state is set on creation.

That is the reason why the example forcefully only allows the socket to be open after auth.

Cheers,
Paulo
Reply all
Reply to author
Forward
0 new messages