Dynamically unsubscribe a user / revoke subscribe permissions?

#1

Hello

I am writing a GPS location sharing app and I am using Crossbar on the server side and Autobahn on the client side to deliver position updates via WAMP messages.

When the user moves, their location is shared by a WAMP message being published.

I’ve written custom authentication and authorization services that authenticate the websocket connections per-user, and an authorization service that determines if said user is on the tracked user’s friends list before allowing the subscription request.

The major issue I have here is that if the user being tracked removes the other user from their friends list, the existing subscription stays where it is, and the subscribed user continues to receive position updates.

So, there’s a few ways this could be fixed. I’m not averse to implementing this functionality in Crossbar itself if I need to, especially if someone tells me where I should look.

Key questions:

  1. Is there a way to remove an existing subscription programatically?

  2. Is there a way to clear the authorization cache so all existing authorizations are re-checked - providing they would be?

  3. If this doesn’t occur, is there a way to drop all the connections for a certain user so that user reconnects and re-subscribes to all the subscriptions?

I’m sure this is a problem for a number of use cases other than my own, so I’d be interested to know how others have solved it.

I haven’t found any answers in the docs, haven’t seen anything promising reading the source code, and searching this list for anything containing “unsubscribe” turns up nearly every message thanks to the footer…

Thanks in advance.

0 Likes

#2

Hi Geordie!

The major issue I have here is that if the user being tracked removes the other user from their friends list, the existing subscription stays where it is, and the subscribed user continues to receive position updates.

Valid use case, though not something we’ve though about explicitly.

Key questions:

  1. Is there a way to remove an existing subscription programatically?

AFAIK there isn’t. Only a subscriber can take actions affecting the existence of the subscription.

  1. Is there a way to clear the authorization cache so all existing authorizations are re-checked - providing they would be?

I have no idea - this is something for Tobias to answer.

  1. If this doesn’t occur, is there a way to drop all the connections for a certain user so that user reconnects and re-subscribes to all the subscriptions?

AFAIK there isn’t. Similarly to the subscriptions, only the client itself can take action here.

I’m sure this is a problem for a number of use cases other than my own, so I’d be interested to know how others have solved it.

I haven’t found any answers in the docs, haven’t seen anything promising reading the source code, and searching this list for anything containing “unsubscribe” turns up nearly every message thanks to the footer…

A couple of suggestions of the top of my head (though I realize these are probably not what you are looking for):

  1. If the client is trusted, then why not have the client itself unsubscribe? The removal from the friends list triggers a Publish to all clients currently connected for the user and tells them to unsubscribe.

  2. You can exclude a client from receiving a subscription, e.g. “session.publish('com.locationapp.user1223.currentlocation”, [], {}, {exclude: [sessionID1, sessionID2]}". If the events are published from a backend which knows of current sessions which are no longer authorized, then these could be handled that way.

Regards,

Alex

0 Likes

#3

Hello

To avoid a repeat of a certain XKCD, I’m going to outline how I think I’ve fixed the problem.

  1. The client (HTML5 webapp) initiates a websocket connection with the Crossbar server.

  2. The client receives a challenge from the server.

  3. The client makes a request from the web server side of the app for an authentication token (it’s logged into the webapp with a cookie-based session).

  4. The client uses this to authenticate the websocket, and the user ID of the client’s account is used as the AuthID.

  5. The server side then verifies the token and checks that the AuthID the client sends is the same as the one the token was generated for. If the client sends the wrong AuthID the token will be rejected.

  6. Another component is registered on wamp.metaevent.session.on_join and wamp.metaevent.session.on_leave and keeps in a separate database a mapping of session IDs to user IDs.

So if this is all successful, we now have the client connection authenticated for that particular user, and a record of it’s session ID in a database.

(the database is cleared on application startup in case the app doesn’t shut down gracefully, and the record is deleted when the client disconnects)

Then, when an “update” event is pushed from the client, a SQL query is executed to JOIN the table of sessions with the table of which users are authorised to see that user’s events. This then produces a list of session IDs which is sent in the “eligible” parameter for the WAMP message, hence if a user is removed, they will immediately not receive any more messages.

It’s not the way I’d like to do it - I’d love to have a way of telling Crossbar to re-evaluate it’s permissions and remove subscriptions that authorisation now fails for - but it seems to be working, and looks like the only practical way to do it now.

Thanks.

···

On 18 Dec 2014, at 11:58 pm, Alexander Gödde alexande...@googlemail.com wrote:

Hi Geordie!

The major issue I have here is that if the user being tracked removes the other user from their friends list, the existing subscription stays where it is, and the subscribed user continues to receive position updates.

Valid use case, though not something we’ve though about explicitly.

Key questions:

  1. Is there a way to remove an existing subscription programatically?

AFAIK there isn’t. Only a subscriber can take actions affecting the existence of the subscription.

  1. Is there a way to clear the authorization cache so all existing authorizations are re-checked - providing they would be?

I have no idea - this is something for Tobias to answer.

  1. If this doesn’t occur, is there a way to drop all the connections for a certain user so that user reconnects and re-subscribes to all the subscriptions?

AFAIK there isn’t. Similarly to the subscriptions, only the client itself can take action here.

I’m sure this is a problem for a number of use cases other than my own, so I’d be interested to know how others have solved it.

I haven’t found any answers in the docs, haven’t seen anything promising reading the source code, and searching this list for anything containing “unsubscribe” turns up nearly every message thanks to the footer…

A couple of suggestions of the top of my head (though I realize these are probably not what you are looking for):

  1. If the client is trusted, then why not have the client itself unsubscribe? The removal from the friends list triggers a Publish to all clients currently connected for the user and tells them to unsubscribe.
  1. You can exclude a client from receiving a subscription, e.g. “session.publish('com.locationapp.user1223.currentlocation”, [], {}, {exclude: [sessionID1, sessionID2]}". If the events are published from a backend which knows of current sessions which are no longer authorized, then these could be handled that way.

Regards,

Alex

You received this message because you are subscribed to the Google Groups “Autobahn” group.

To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.

To post to this group, send email to autob...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/autobahnws/466e31a7-d961-4e92-b6f5-4f3db3b956ff%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

0 Likes

#4

Hi Geordie,

sorry, I missed that thread. We first need to establish what you want.

1)
A session that subscribed to a topic can dynamically unsubscribe itself later on (while the session is still ongoing).

I guess that's clear to you already, but not what you want, right?

2)
Say a session S1 authenticated under role R1 was authorized to subscribe and did actually subscribe to topic T1.

Now say the authorization to subscribe to topic T1 is removed from role R1.

_New_ sessions authenticating as R1 cannot any longer subscribe to T1.

Further, when S1 unsubscribes (itself), and then again tries to subscribe to T1, that will fail.

However, when the _existing_ session S1 has an _established_ subscription to T1, and _that_ subscription is _not_ kicked by the router.

Is that the issue we are talking about?

3)
Say a session S1 authenticated under role R1 was authorized to subscribe and did actually subscribe to topic T1.

A conceivable feature would be for _another_ session S2 (say some kind of backend management session) being able to actively kick the subscription of S1 to T1 (independent of retaining or revoking the _authorization_ of R1 to subscribe T1).

Is that the feature you want?

Cheers,
/Tobias

···

Am 06.01.2015 um 11:06 schrieb Geordie Millar:

Hello

To avoid a repeat of a certain XKCD, I'm going to outline how I think
I've fixed the problem.

1. The client (HTML5 webapp) initiates a websocket connection with the
Crossbar server.
2. The client receives a challenge from the server.
3. The client makes a request from the web server side of the app for an
authentication token (it's logged into the webapp with a cookie-based
session).
4. The client uses this to authenticate the websocket, and the user ID
of the client's account is used as the AuthID.
5. The server side then verifies the token and checks that the AuthID
the client sends is the same as the one the token was generated for. If
the client sends the wrong AuthID the token will be rejected.
6. Another component is registered on wamp.metaevent.session.on_join
and wamp.metaevent.session.on_leave and keeps in a separate database a
mapping of session IDs to user IDs.

So if this is all successful, we now have the client connection
authenticated for that particular user, and a record of it's session ID
in a database.
(the database is cleared on application startup in case the app doesn't
shut down gracefully, and the record is deleted when the client disconnects)

Then, when an "update" event is pushed from the client, a SQL query is
executed to JOIN the table of sessions with the table of which users are
authorised to see that user's events. This then produces a list of
session IDs which is sent in the "eligible" parameter for the WAMP
message, hence if a user is removed, they will immediately not receive
any more messages.

It's not the way I'd like to do it - I'd love to have a way of telling
Crossbar to re-evaluate it's permissions and remove subscriptions that
authorisation now fails for - but it seems to be working, and looks like
the only practical way to do it now.

Thanks.

On 18 Dec 2014, at 11:58 pm, Alexander Gödde >> <alexande...@googlemail.com >> <mailto:alexande...@googlemail.com>> wrote:

Hi Geordie!

    The major issue I have here is that if the user being tracked
    removes the other user from their friends list, the existing
    subscription stays where it is, and the subscribed user continues
    to receive position updates.

Valid use case, though not something we've though about explicitly.

    Key questions:

    1) Is there a way to remove an existing subscription programatically?

AFAIK there isn't. Only a subscriber can take actions affecting the
existence of the subscription.

    2) Is there a way to clear the authorization cache so all existing
    authorizations are re-checked - providing they would be?

I have no idea - this is something for Tobias to answer.

    3) If this doesn't occur, is there a way to drop all the
    connections for a certain user so that user reconnects and
    re-subscribes to all the subscriptions?

AFAIK there isn't. Similarly to the subscriptions, only the client
itself can take action here.

    I'm sure this is a problem for a number of use cases other than my
    own, so I'd be interested to know how others have solved it.

    I haven't found any answers in the docs, haven't seen anything
    promising reading the source code, and searching this list for
    anything containing "unsubscribe" turns up nearly every message
    thanks to the footer...

A couple of suggestions of the top of my head (though I realize these
are probably not what you are looking for):

1. If the client is trusted, then why not have the client itself
unsubscribe? The removal from the friends list triggers a Publish to
all clients currently connected for the user and tells them to
unsubscribe.

2. You can exclude a client from receiving a subscription, e.g.
"session.publish('com.locationapp.user1223.currentlocation", [], {},
{exclude: [sessionID1, sessionID2]}". If the events are published from
a backend which knows of current sessions which are no longer
authorized, then these could be handled that way.

Regards,

Alex

--
You received this message because you are subscribed to the Google
Groups "Autobahn" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to autobahnws+...@googlegroups.com
<mailto:autobahnws+...@googlegroups.com>.
To post to this group, send email to autob...@googlegroups.com
<mailto:autob...@googlegroups.com>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/autobahnws/466e31a7-d961-4e92-b6f5-4f3db3b956ff%40googlegroups.com
<https://groups.google.com/d/msgid/autobahnws/466e31a7-d961-4e92-b6f5-4f3db3b956ff%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google
Groups "Autobahn" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to autobahnws+...@googlegroups.com
<mailto:autobahnws+...@googlegroups.com>.
To post to this group, send email to autob...@googlegroups.com
<mailto:autob...@googlegroups.com>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/autobahnws/A6344EAB-E1EF-4CCD-BD83-9EFF8B2E8F1C%40stackunderflow.com
<https://groups.google.com/d/msgid/autobahnws/A6344EAB-E1EF-4CCD-BD83-9EFF8B2E8F1C%40stackunderflow.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.

0 Likes

#5

Hi Geordie,

sorry, I missed that thread. We first need to establish what you want.

A session that subscribed to a topic can dynamically unsubscribe itself later on (while the session is still ongoing).

I guess that’s clear to you already, but not what you want, right?

Yes, that’s clear, but I want the subscription revoked from the user side because user A has deleted user B, and user B’s client need not be trusted.

Say a session S1 authenticated under role R1 was authorized to subscribe and did actually subscribe to topic T1.

Now say the authorization to subscribe to topic T1 is removed from role R1.

New sessions authenticating as R1 cannot any longer subscribe to T1.

Further, when S1 unsubscribes (itself), and then again tries to subscribe to T1, that will fail.

However, when the existing session S1 has an established subscription to T1, and that subscription is not kicked by the router.

Is that the issue we are talking about?

Yes, this is exactly the issue that I want. I would like a way for S1 to be automatically dropped from it’s subscription to T1 as soon as S1 is no longer allowed to subscribe to T1.

Say a session S1 authenticated under role R1 was authorized to subscribe and did actually subscribe to topic T1.

A conceivable feature would be for another session S2 (say some kind of backend management session) being able to actively kick the subscription of S1 to T1 (independent of retaining or revoking the authorization of R1 to subscribe T1).

Is that the feature you want?

Cheers,
/Tobias

Thanks

Geordie Millar

···

On 7 Jan 2015, at 8:43 pm, Tobias Oberstein tobias.o...@gmail.com wrote:

Am 06.01.2015 um 11:06 schrieb Geordie Millar:

Hello

To avoid a repeat of a certain XKCD, I’m going to outline how I think
I’ve fixed the problem.

  1. The client (HTML5 webapp) initiates a websocket connection with the
    Crossbar server.
  2. The client receives a challenge from the server.
  3. The client makes a request from the web server side of the app for an
    authentication token (it’s logged into the webapp with a cookie-based
    session).
  4. The client uses this to authenticate the websocket, and the user ID
    of the client’s account is used as the AuthID.
  5. The server side then verifies the token and checks that the AuthID
    the client sends is the same as the one the token was generated for. If
    the client sends the wrong AuthID the token will be rejected.
  6. Another component is registered on wamp.metaevent.session.on_join
    and wamp.metaevent.session.on_leave and keeps in a separate database a
    mapping of session IDs to user IDs.

So if this is all successful, we now have the client connection
authenticated for that particular user, and a record of it’s session ID
in a database.
(the database is cleared on application startup in case the app doesn’t
shut down gracefully, and the record is deleted when the client disconnects)

Then, when an “update” event is pushed from the client, a SQL query is
executed to JOIN the table of sessions with the table of which users are
authorised to see that user’s events. This then produces a list of
session IDs which is sent in the “eligible” parameter for the WAMP
message, hence if a user is removed, they will immediately not receive
any more messages.

It’s not the way I’d like to do it - I’d love to have a way of telling
Crossbar to re-evaluate it’s permissions and remove subscriptions that
authorisation now fails for - but it seems to be working, and looks like
the only practical way to do it now.

Thanks.

On 18 Dec 2014, at 11:58 pm, Alexander Gödde > > > <alexande...@googlemail.com > > > mailto:alexande...@googlemail.com> wrote:

Hi Geordie!

The major issue I have here is that if the user being tracked
removes the other user from their friends list, the existing
subscription stays where it is, and the subscribed user continues
to receive position updates.

Valid use case, though not something we’ve though about explicitly.

Key questions:

  1. Is there a way to remove an existing subscription programatically?

AFAIK there isn’t. Only a subscriber can take actions affecting the
existence of the subscription.

  1. Is there a way to clear the authorization cache so all existing
    authorizations are re-checked - providing they would be?

I have no idea - this is something for Tobias to answer.

  1. If this doesn’t occur, is there a way to drop all the
    connections for a certain user so that user reconnects and
    re-subscribes to all the subscriptions?

AFAIK there isn’t. Similarly to the subscriptions, only the client
itself can take action here.

I’m sure this is a problem for a number of use cases other than my
own, so I’d be interested to know how others have solved it.

I haven’t found any answers in the docs, haven’t seen anything
promising reading the source code, and searching this list for
anything containing “unsubscribe” turns up nearly every message
thanks to the footer…

A couple of suggestions of the top of my head (though I realize these
are probably not what you are looking for):

  1. If the client is trusted, then why not have the client itself
    unsubscribe? The removal from the friends list triggers a Publish to
    all clients currently connected for the user and tells them to
    unsubscribe.

  2. You can exclude a client from receiving a subscription, e.g.
    “session.publish('com.locationapp.user1223.currentlocation”, [], {},
    {exclude: [sessionID1, sessionID2]}". If the events are published from
    a backend which knows of current sessions which are no longer
    authorized, then these could be handled that way.

Regards,

Alex


You received this message because you are subscribed to the Google
Groups “Autobahn” group.
To unsubscribe from this group and stop receiving emails from it, send
an email to autobahnws+...@googlegroups.com
mailto:autobahnws+...@googlegroups.com.
To post to this group, send email to autob...@googlegroups.com
mailto:autob...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/autobahnws/466e31a7-d961-4e92-b6f5-4f3db3b956ff%40googlegroups.com
<https://groups.google.com/d/msgid/autobahnws/466e31a7-d961-4e92-b6f5-4f3db3b956ff%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.


You received this message because you are subscribed to the Google
Groups “Autobahn” group.
To unsubscribe from this group and stop receiving emails from it, send
an email to autobahnws+...@googlegroups.com
mailto:autobahnws+...@googlegroups.com.
To post to this group, send email to autob...@googlegroups.com
mailto:autob...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/autobahnws/A6344EAB-E1EF-4CCD-BD83-9EFF8B2E8F1C%40stackunderflow.com
<https://groups.google.com/d/msgid/autobahnws/A6344EAB-E1EF-4CCD-BD83-9EFF8B2E8F1C%40stackunderflow.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.


You received this message because you are subscribed to the Google Groups “Autobahn” group.
To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.
To post to this group, send email to autob...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/autobahnws/54AD06B1.2090205%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

0 Likes

#6

2)
Say a session S1 authenticated under role R1 was authorized to
subscribe and did actually subscribe to topic T1.

Now say the authorization to subscribe to topic T1 is removed from
role R1.

_New_ sessions authenticating as R1 cannot any longer subscribe to T1.

Further, when S1 unsubscribes (itself), and then again tries to
subscribe to T1, that will fail.

However, when the _existing_ session S1 has an _established_
subscription to T1, and _that_ subscription is _not_ kicked by the router.

Is that the issue we are talking about?

Yes, this is exactly the issue that I want. I would like a way for S1 to
be automatically dropped from it's subscription to T1 as soon as S1 is
no longer allowed to subscribe to T1.

Ok.

First, this would be a feature of a specific WAMP router - not WAMP as a protocol per-se (but see below).

Then, this feature isn't implemented in Crossbar.io as of today.

There are noteworthy aspects:

1)
Crossbar.io when using a static node configuration (read from .crossbar/config.json) sets up role permissions, and due to the fact that the node config is only read at startup, it cannot change anyway.

Changing the permissions of a role in Crossbar.io dynamically is (partially) already possible today - but not officially supported yet (the "management API").

2) If you implement a custom WAMP authorizer for use with Crossbar.io (ping me if it's unclear what I mean), the authorizer is only called for the initial authorization request ("is this session allowed to subscribe T1"), might be cached, but in any case (cached or not), changing the role's permissions afterwards won't kick existing subscriptions (see 1.)

3) When we implement 1./2., there is this issue left: when a session subscribes, and the session is not authorized, it'll get an error (the subcsribe fails). This is clear and transparent to the client app.

However, what should happen when the subscription is later revoked? The client won't notice! This is somehow not satisfying (lack of transparency).

How should we notice a subscribed session that it's subscription has been revoked?

Cheers,
/Tobias

0 Likes