readium / r2-streamer-js

NodeJS Readium2 "streamer"
BSD 3-Clause "New" or "Revised" License
21 stars 10 forks source link

Streamer doesn't response encrypted publication resources without browse manifestjson page #43

Closed nguyenhuutuananh closed 5 years ago

nguyenhuutuananh commented 5 years ago

Hi @danielweck,

I found that if I not browse ./manifest.json/show/all page, i will get error r2:lcp#transform/transformer-lcp LCP not ready! image

My solution

Did i miss something?
I'm very interested in streamer can stream data.

Thank you

danielweck commented 5 years ago

Actually, this is the "normal" behaviour (intentionally implemented that way). See documentation: https://github.com/readium/r2-streamer-js/blob/develop/docs/encryption.md#lcp-drm (you may try the step-by-step instructions yourself, by clicking on the links)

But remember, this feature (i.e. "passphrase hash passed into manifest.json URL in order to initialize the internal publication state") is only designed for testing, this is not really suitable for robust production scenarios. Your feedback / suggested improvements / Pull Requests would be welcome! (for example, an alternative method based on custom HTTP headers instead of this bespoke / arbitrary URL path scheme)

danielweck commented 5 years ago

Generally-speaking, a notable caveat is that once the LCP passphrase has been validated / accepted by the server (i.e. correct SHA256 passed into the manifest.json URL), then internally ; as part of the streamer state ; the loaded Publication object is "ready" to decrypt any subsequent resources without providing the passphrase again, for anybody who make requests to the public URLs. For example, user A sets the correct passphrase to access publication X, then user B, C, D etc. can read the contents of publication X too!

You would need to add an additional logical layer if you want to restrict user access to specific publication URLs. This could be as simple as an authorization bearer HTTP header for pre-defined, restricted routes (for example, only user A username/password combination can access publication X URL path ... you could even automatically derive the LCP passphrase from the username/password credentials). There are of course more sophisticated ways to implement this (e.g. proper OAuth etc. user sessions), I am just giving the most basic example as a starting point.

danielweck commented 5 years ago

Right now, the primary integration context for the NodeJS / TypeScript implementation of the Readium2 streamer is the "desktop app" (Electron), which is basically a local deployment of the client/server architecture, with the expectation that a single user (i.e. the owner of the computer on which the app is installed) has access to his/her own collection of publications. Furthermore, the HTTP server is started/shutdown whenever appropriate, so the internal state of loaded publications is reset at regular intervals (the LCP passphrase hash is made persistent inside the app settings database, so that the user only has to provide it once).

A "true" online client/server scenario would require some alterations to the streamer logic, or at the very least a reworked definition of the server state (i.e. loaded publications), so that support for multiple users is secure / properly fenced-off.