crossbar
crossbar copied to clipboard
feature request: Add a meta-API call to remove cookies related to a specified authid
you can kill all sessions for a given authid using wamp.session.kill_by_authid
and provide wamp.close.logout
as reason
https://github.com/crossbario/crossbar/blob/42b8bf95a29f17724f2ec120cd3a6ad096d5b396/crossbar/router/service.py#L445
this should actually have the desired effect of removing the cookies (when the given authid actually has an authenticated cookie)
this is slightly different from deleting the cookies without killing the sessions, and it also only allows to handle 1 authid (not a list as you seem to hint) .. but I'd try above first anyways ..
rgd "slightly different":
- extending the meta API to accept lists of
authids
rather than a singleauthid
is redundant: just iterate over your list client side and issue multiple calls - adding meta API procedures to allow deleting cookies without killing sessions would expose authentication method specifics in the meta API, which breaks the API design
IOW: if so, then such methods should be added as procedures to the authenticator itself - not the general meta API. that's possible and in fact easy, the question is: do we really want that / is it a good idea?
rgd "authenticator API": this is currently designed to be as simple as possible, and identical (at the WAMP call/call-result signature type level) for all authentication methods
https://github.com/wamp-proto/wamp-proto/blob/ae4765ee6ed1d9e7409f06c9af9082ea03ac7b1d/catalog/src/wamp-auth.fbs#L105
"delete cookies for list of authids": would be a procedure completely specific to a single authentication method ("cookie")
ok, the method you mention here will be good for existing sessions.
you can kill all sessions for a given authid using
wamp.session.kill_by_authid
and providewamp.close.logout
as reason
Iterating over a list of authids in the application code is fine. I'll adjust the title.
I think there should be a way to delete the cookies of a user independent of an existing session:
use cases:
This is necessary if you want to forcefully logout a user from all browsers, e.g. because a "recover password" procedure has been started. Or the user has logged in on another persons computer and has no access to that computer anymore and needs to log out remotely.
Thanks for describing the use case!
Or the user has logged in on another persons computer and has no access to that computer anymore and needs to log out remotely.
So that means, the user will authenticate (*) using an authentication method different from WAMP-Cookie, and once successfully authenticated, it can issue a call to an application backend procedure, which in turn will call into NEW-API to delete any cookie that happens to be stored (and authenticated) in e.g. a File-based or a Database-based Crossbar.io cookie store.
Note that this should then work even though the user in (*) did not present the cookie to be deleted. Also note that the call into NEW-API is not done directly from the user client (which you could in principle configure permissions to allow, but ..), but done indirectly from application backend code. This seems preferable.
Is that what you have in mind?
If so, then placing NEW-API into IWampAuthenticate
would be wrong, as that interface is supposed to be generic (same signature independent of specific authentication method).
Placing NEW-API into a specialized IWampAuthenticateCookie
would be wrong as well, for two reasons, first because that interface is for dynamic authentication, which for Cookies doesn't apply as WAMP-TLS and WAMP-Cookie are transport level authenticators (outside WAMP authentication handshake), and second because you actually want to have NEW-API sitting on top of a Crossbar.io built-in implementation of Cookie store - which handles authentication without dynamically calling any user code anyways.
Consequently, NEW-API should be registered and provided by cookie.store
of type database
- IOW, this database cookie store should provide a dynamic authentication management ICookieStore API
Right?
https://github.com/crossbario/crossbar-examples/blob/4ebd3299b1bdd519d199100a446478443cf2a54a/authentication/cookie/.crossbar/config-database.json#L116 https://github.com/crossbario/crossbar/blob/master/crossbar/router/cookiestore.py#L426
This new ICookieStore
API could then include a procedure
-
crossbar.cookiestore.delete_by_authid
which would delete a cookie based on authid
.
It might also have an option to also kill any sessions with that authid
.
The ICookieStore
API would be registered on a configurable realm-role:
"cookie": {
"store": {
"type": "database",
"path": ".cookies",
"purge_on_startup": false,
"maxsize": 1048576,
"readonly": false,
"sync": true,
"realm": "realm1",
"role": "backend"
}
}
Is that what you have in mind?
Yes, an independently authorized backend procedure would interact with the cookie store.
Consequently, NEW-API should be registered and provided by cookie.store of type database - IOW, this database cookie store should provide a dynamic authentication management ICookieStore API
Sounds reasonable to me.
Awesome! We're on the same page;) And above is a sufficiently precise definition to implement.
It might also have an option to also kill any sessions with that authid
I kind of would not mix these things here. If someone wants to kill sessions too, then he/she just has to call the wamp.session.kill additionally. just my opinion
I kind of would not mix these things here.
yeah, not completely sure either. it's a detail, not that crucial. fwiw, my thinking was: yes, it is mixing, but so is wamp.session.kill_by_authid
as it provides the option to magically delete cookies (a management op) by simply providing wamp.close.logout
. which is mixing, and is indeed borderline hackish / questionable as well. anyways, details;)
@markope regarding version 21.3.1 and below
I also wanted this functionality: independently authorized backend procedure to interact with the cookie store. So I rolled my own Postgresql cookie storage table functionality, adding additional columns to the table to store additional dict keys to the existing cookie dict, then added it as an option to the file-based and memory-based methods.
Caution if trying this!
Adding a cookie-database feature involved me tinkering with key python modules of Crossbar. I realize how important it is for Crossbar.io and the community in general to have rock-solid reliability, so I didn't even try to do a pull request, especially as new versions may have solved it. Mine is not a general use case: all my production servers use wampcra, dynamic authorization and Postgres, yet there are so many other ways to run Crossbar. One tip: run a completely isolated dev instance in a vm when tinkering so if/when you mess it up, simply remove the vm along with Crossbar and start over.
Similar features may now exist in versions > 21.3.1
Crossbar versions more recent than 21.3.1 shipped since this post began. I haven't run the newest version in production, but I did peek through the new codebase and it does include db cookie storage, so my response may only be useful to those running 21.3.1.
For the inquisitive who run 21.3.1, use wampcra, dynamic auth and Postgres:
I added an optional flag in config.json so that on router restart if I include that flag it defaults to using a database for cookie management. Then I simply created a few rRPCs to trigger stored Postgresql functions written in PL/pgSQL to validate any user input to be injection-safe. It works wonderfully and I have total control now over users that I need to logout and manage their cookie trail.
When I began coding this new feature, I found there is a tiny glitch in the existing codebase regarding UTCnow, harmless in Crossbar but fails when binding/porting the timestamp variable to Postgresql. I patched it easily for my use case. As it was a very minor but concrete improvement for the community, I thought I'd make a pull request just for the UTCnow fix. For some reason this tiny change failed two key tests and I tried for days to resolve those two tests. Tobias also tried to help me find why (how does Tobias and the other core developers find time to help all of us?!?), but really it was such a very small change to a critical file that works for everyone else, so not worth tracking down the reason.
Here are the files I had to patch (assume you have a linux vm from which you start crossbar):
~/vm/lib/python3.9/site-packages/crossbar/common/checkconfig.py
def check_cookie_store_file(store):
check_dict_args({
'type': (True, [str]),
'filename': (False, [str]),
'purge_on_startup': (False, [bool]),
'db': (False, [bool])
}, store, "WebSocket memory-backed cookie store configuration")
~/vm/lib/python3.9/site-packages/crossbar/router/protocol.py (no change, but I include this non-change here because initially I did lots of changes to this file, then later found with refactoring that I didn't need to modify it)
~/vm/lib/python3.9/site-packages/crossbar/router/cookiestore.py (many changes, including the utcnow pull-request on github)
If you use dynamic authentication with Postgres you'll have to make changes to authenticator.py. I added registration defs in there for the new rRPCs (probably not good separation of concerns, so I'm sure others would do that better!).
Hope my experience may help a few others who are thinking of adding database-managed cookies/authids to older versions.