Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSocket protocol format and definition #3

Closed
acoburn opened this issue Sep 20, 2019 · 15 comments
Closed

WebSocket protocol format and definition #3

acoburn opened this issue Sep 20, 2019 · 15 comments
Assignees
Labels

Comments

@acoburn
Copy link
Member

acoburn commented Sep 20, 2019

The 0.8 Solid specification includes a WebSocket API, which defines a simple line-based interaction between client and server. For example, here is a subscription to a container followed by two notifications for child resources that are created:

> sub https://example.com/container
< pub https://example.com/container/1
< pub https://example.com/container/2

That design has the advantage of being simple to implement and simple to consume. That said, most WebSocket APIs that I have encountered use a JSON-based format, which provides a more structured format for consumption (the format could even be compact JSON-LD) along with easier points for extension (e.g. what if other keywords are to be added?).

In addition, the JavaScript API for WebSockets (WebSocket(url[, protocols])) includes an optional protocols parameter. If this interaction is formalized, would it make sense to define a solid protocol that could be used for WebSocket interactions?

@RubenVerborgh
Copy link
Contributor

Indeed, we would need to engineer the protocol properly (see solid/specification#50). JSON(-LD) could be a good candidate.

@timbl
Copy link

timbl commented Sep 27, 2019

PlanA at back in the day to take this question toward using patches in N3 so that the metadata about the patch (user, time, etc) could be put in as well as the changes (deletions, insertions). Ruben implemented N3 patch format in rdflib.js. The changes made by the UpdateManager in the client would be very easy to serialize in this this way.

This is long term goal. It connects of course with transaction logging on the server. local-first, offline first, and peer-peer networks as enhancements on the current server hub/spoke topology. We should not try to combine this enhancement with the authentication of WS bug fix.

@RubenVerborgh
Copy link
Contributor

@timbl I would argue that authentication is more than a bug fix.

It's not just authentication that was forgotten, there are some other essential decisions in the protocol that are problematic. The fact that such basic things were overlooked, indicates to me that the WebSockets draft was not designed with sustainability in mind. I have strong doubts about the design quality of the WebSockets draft in general, and think it is unwise to spec it as is. I don't see it pass quality assessments.

I do acknowledge that the current draft was a quick way to address a real and important need. And I think we should just see it as that: an experiment to show that it works. Now that we know it does, we should actually design a protocol.

@timbl
Copy link

timbl commented Sep 27, 2019

Sure lets design a nice new future protocol. But mean the lack of authentication is a serious bug with the current protocol. And current code and current apps use this feature. So we need to solve that problem urgently, on a timescale which I think will not wait for the new protocol for downstream patches.

@RubenVerborgh
Copy link
Contributor

Agreed on fixing fast for apps currently in use. Just have doubts about spec'ing it, as we know it is not the sustainable protocol we want. Can it stay unspec'ed for the time being?

@d-a-v-i--
Copy link

I understand there is desire to look at other protocols and this will take time. Meanwhile I've cut a quick draft for WebSocket authentication and my aim is to make it generic enough to work on whatever protocol we choose.

@michielbdejong
Copy link
Contributor

I've cut a quick draft for WebSocket authentication

@d-a-v-i-- that is requiring clients to send the auth <bearer_token> command when they connect, right?

@michielbdejong
Copy link
Contributor

@acoburn did you do any work on the auth command since this? I'm about to implement it in rdflib.

@michielbdejong
Copy link
Contributor

The thing that's slightly awkward about it is that we now have 2 auth headers to send, Authorization and DPop. So I was thinking of instead of creating one auth command and wrapping both into the parameters somehow, we could do:
Suppose that the client sends the http request headers like in Figure 4 then on the WebSocket you could achieve the same by sending two corresponding auth-header commands:

auth-header Authorization: DPoP eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwczovL3Jlc291cmNlLmV4YW1wbGUub3JnIiwibmJmIjoxNTYyMjYyNjExLCJleHAiOjE1NjIyNjYyMTYsImNuZiI6eyJqa3QiOiIwWmNPQ09SWk5ZeS1EV3BxcTMwalp5SkdIVE4wZDJIZ2xCVjN1aWd1QTRJIn19.vsFiVqHCyIkBYu50c69bmPJsj8qYlsXfuC6nZcLl8YYRNOhqMuRXu6oSZHe2dGZY0ODNaGg1cg-kVigzYhF1MQ
auth-header DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCRnMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiJlMWozVl9iS2ljOC1MQUVCIiwiaHRtIjoiR0VUIiwiaHR1IjoiaHR0cHM6Ly9yZXNvdXJjZS5leGFtcGxlLm9yZy9wcm90ZWN0ZWRyZXNvdXJjZSIsImlhdCI6MTU2MjI2MjYxOH0.lNhmpAX1WwmpBvwhok4E74kWCiGBNdavjLAeevGy32H3dbF0Jbri69Nm2ukkwb-uyUI4AUg1JSskfWIyo4UCbQ

@acoburn
Copy link
Member Author

acoburn commented Aug 26, 2020

I currently have this implemented as a finite state machine with the following states:
Unauthenticated, AwaitingDPoP, Authenticated and Error. All interactions start with Unauthenticated and once Error is reached, the session has to be restarted in order to proceed.

The websocket keywords are auth and dpop. For instance:

auth <bearer token>
dpop <dpop token>

Responses are either err or ack <keyword> (e.g. ack auth)

(So I'm not using the Authorization: DPoP or DPoP: prefixes)

This does work, but I don't like it.

One idea (currently unimplemented) is for the WebSocket server to act as an OIDC relying party, so before a JavaScript client establishes a connection, there is a login flow that generates a cookie-based session. That cookie is then automatically sent as part of the new WebSocket(url) browser interaction, and it is from that cookie that authN information is determined.

That sort of interaction vastly simplifies the WebSocket protocol. It also makes it possible to use DPoP as it was intended to be used -- for ordinary HTTP methods. DPoP doesn't make any sense in the context of WebSockets, since there's no method (htm) as part of the request, and the url (htu) is arguably not relevant.

@elf-pavlik
Copy link
Member

Recent Google Chrome Developers video - Streaming requests with fetch - HTTP 203 provides some interesting updates. It even discusses having two fetches for bidirectional communication if needed (at 16:09). I think we should seriously evaluate streaming HTTP responses before committing to WebSockets.

@michielbdejong
Copy link
Contributor

I'll align to use auth <bearer token> / dpop <dpop token> instead of auth-header.

@csarven csarven transferred this issue from solid/specification Sep 24, 2021
@RubenVerborgh
Copy link
Contributor

@csarven csarven transferred this issue from solid/notifications-panel Oct 27, 2021
@csarven csarven added the model label Nov 29, 2022
@csarven csarven self-assigned this Nov 29, 2022
@csarven
Copy link
Member

csarven commented Nov 29, 2022

The data format is JSON-LD. The data model is defined by https://solid.github.io/notifications/protocol#notification-data-model (with proposed update as of this writing: #124 ) and further specifics on WebSocket in https://solid.github.io/notifications/websocket-subscription-2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants