[JS] Add Bearer-Token based authentication
w4tsn opened this issue · 8 comments
Ditto currently support basic auth, google JWT and OpenID Connect tokens. In order for the last two to work a Bearer token class is required.
Open Questions
Is it possible in the websocket-implementation of this project, to have custom headers in the websocket connection request? This is required to enable header-based token authentication on websocket connections. Ditto itself supports this mechanism, browser implementations of the websocket protocol don't. This is a requirement to add full bearer-token support for websocket and http APIs.
Implementation
I propose to add a simple first bearer-token class with basic PoC-level functionality similar to the basic auth classes.
I can do this and file a PR.
Hi @w4tsn
to my knowledge it is not possible to send custom headers with a websocket request in the browser as the underlying implementation doesn't allow it.
In our commercial offering we think about implementing a cookie based authentication for websockets in the browser. The cookie would be offered by an authorization server running on the same domain as our service. The client could then use the cookie to authenticate it's websocket request.
I thought this library would not relay on the browser implementation of websockets and instead implement it itself. There are other browser-compatible implementations of the websocket protocol implementing additional header support, although this is not part of the standard and mostly requires a custom server-side as well.
I'm with you that, if the websocket implementation does not support headers, cookies are the way to go.
So do you think it's better, in case of websockets, to have the surrounding client-application handle the authentication with the endpoint / cookies and assume that this ditto-client will then act with a pre-established cookie based authentication?
The Ditto Javascript client for using in browser is also using the plain WebSocket
.
So also no headers available there.. 😒
The longer we talk about this problem the more I think that we should allow sending such data via the Websocket "sub protocols" feature.
See also this proposal: https://stackoverflow.com/a/4361358/5058051
I really dislike the alternative to send authentication related information as query params as some proxies or load balancers in between could log the token then (when not doing the ssl termination in Ditto).
Cookies would also be a good alternative, however Ditto relies that authentication is done elsewhere, so it should not set the Cookie itself IMHO.
Is ditto able to read the token from a cookie, or is only the Authorization: Bearer ...
header supported?
If cookies would work, I could think of using a self-hosted gatekeeper
that is responsible for getting the token and setting a cookie or having the frontend application handle the logic and setting the cookie.<
Edit Of course if there is a proxy in between one could also read the token from the cookie and set it as header, if ditto doesn't support cookies. This would however introduce the need of a third-party application in between the ditto js dom client and ditto itself.
Ditto does not (yet) support reading from cookies.
A self-hosted gatekepper
could to the Cookie-To-Header rewriting as well as setting the cookie, couldn't it?
And yes, this would be a 3rd party app in between Ditto js dom client and Ditto.
Yeah, the gatekeeper issues a cookie to the client if authenticate successfully (I think we had to trick it into it though, because with valid access token it just passes through) BUT we ran into the problem that the gatekeeper does not accept websocket connections. If it would except websocket connections and add the auth header on the other side on it's way to ditto that would be nice, but we couldn't get this to work.
Oh, too bad.
We would definitely do such things in nginx (acting as a gatekeeper for us), e.g. that way: https://stackoverflow.com/a/39353517/5058051