deepstreamIO/deepstream.io

Check client's uid in HTTP auth?

kyeno opened this issue · 5 comments

kyeno commented

Hey,
I have a certain authentication flow that by design should rely on uid()'s quite a bit.

Upon connection and before authentication the client stores it's uid (deepstream.getUid()), mangles it and sends it over with few other params to in the deepstream.login() object.

Then the auth is redirected to local HTTP express server.
I want that HTTP to be aware of the client's Uid and for falseproofing - to fetch it from the server, not from the client... but can't find a way. Console logging connectionData and authData do not give me this information.

I tried "experimenting" a bit with deepstream server's config.yml too, but couldn't really find a good documentation for it.

  - type: http
    options:
        # a post request will be send to this url on every incoming connection
        endpointUrl: http://127.0.0.1:9387/auth
        # any of these will be treated as access granted
        permittedStatusCodes: [ 200 ]
        # if the webhook didn't respond after this amount of milliseconds, the connection will be rejected
        requestTimeout: 2000
        # promote the following items from the login auth data into headers
        promoteToHeader:
           - token
           - uid
        # the codes which the auth handler should retry. This is useful for when the API you depend on is
        # flaky or going through a not so blue/green deployment
        retryStatusCodes: [ 404, 504 ]
        # the maximum amount of retries before returning a false login
        retryAttempts: 3
        # the time in milliseconds between retries
        retryInterval: 5000

The - uid is part of my experiment.
How do I achieve this?

are you logging in with client.login({ uid: 'uid goes here' })?

kyeno commented

are you logging in with client.login({ uid: 'uid goes here' })?

That's exactly what I want to avoid in the first place.
If the message is on the client and sent from the client then in theory it could be modified from the client.

Anyway, if the uid is generated on the client and server is not aware of it, is there any other variable that is generated on the server (or I could generate it there) and pushed to the client on connection, before auth?

Theres a connection uid per socket on the server, but that isn't shared with the client, and is usually just used to index things.

You could add it as a header on the websocket upgrade response object as well. Although you would need to slightly change the code to create the uuid before the server. That way the UID could exist as a header.

You could also add the connection uid to the CHALLENGE message (which is before auth). That would be need to be added into the server/protobuf/client library though. A couple lines per repo but still 4 repos so not a small change.

This work also falls under another issue we want to have where we send some serverConfig to the client on startup as well, like heartbeat intervals and timeouts. Otherwise we end up with config options that conflict occasionally.

Not sure when that will be implemented though, deepstream is in maintenance mode nowadays as current contributors are a bit busy. Happy to code review and provide any help with doing any of this and getting it into master though!

kyeno commented

Hey, thank you for robust explanation. I might actually do that. 👍

Main reason behind this being a pretty tricky authentication mechanic I'm trying to implement; one combined with blockchain verification, but you could also think of normal PGP-keys as well.

The server sends you a message and asks you to sign it, then on the auth process it verifies that. It is quite important at this point that the message itself remains server-generated without the ability to be modified by the client at all.

I will let you know how this evolve and if I will have time to implement such feature with a PR. :)

Hi, I'm gonna close this for now, please feel free to implement the feature and make a pull request, cheers!