Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Implemented authentication and authorization for WebSocket connections in node-solid-server
Summary
Implemented authentication and authorization for WebSocket connections in node-solid-server, enforcing ACL Read permissions before allowing subscriptions. Supports both session cookie and Bearer token authentication methods.
Motivation
WebSocket subscriptions previously lacked authentication and authorization checks, allowing any client to subscribe to resource updates regardless of ACL permissions. This posed a security risk where unauthorized users could monitor changes to private resources.
Changes
1. WebSocket Authorization Infrastructure
Modified
node-solid-ws/lib/server.jsauthorizecallback option to WebSocket server constructorerr <uri> forbiddenwhen authorization failsack <uri>on successful authorizationauthorizecallback provided, subscriptions proceed without checksModified
lib/create-server.mjs- Authorization callback (lines 210-270)authorizeSubscriptioncallback functionACLChecker.can(userId, 'Read')2. Session Cookie Authentication for WebSockets
Modified
lib/create-server.mjs- Upgrade handler (lines 107-140)request.session.userId3. Bearer Token Authentication for WebSockets
Modified
lib/create-server.mjs- Upgrade handler (lines 141-198)Authorization: Bearer <token>header if no session foundoidc.rs.authenticate()) for token validationoidc.webIdFromClaims()DPoP,Bearer)4. Async Authentication Pattern
Implementation Details:
authPromise(async IIFE)Authentication Flow:
Tests
Added comprehensive test coverage:
node-solid-server Tests (7 tests added)
File:
test/integration/authentication-oidc-test.mjsSession Cookie Authentication (4 tests):
should allow authenticated WebSocket subscription to private resourceshould deny anonymous WebSocket subscription to private resourceshould allow authenticated subscription to public resourceshould allow anonymous subscription to public resourceBearer Token Authentication (3 tests):
should allow Bearer token WebSocket subscription to private resourceshould allow Bearer token WebSocket subscription to public resourceshould degrade gracefully with invalid Bearer tokenTest Results: 872 passing (15s)
node-solid-ws Tests (3 tests added)
File:
test/websockets.jsAuthorization Callback Suite:
should receive ack when authorization allows subscriptionshould receive err when authorization denies subscriptionshould receive err when authorization callback returns errorTest Results: 8 passing (82ms)
Test Infrastructure Changes
Modified:
test/resources/accounts-scenario/alice/.acl-overridefoaf:AgentagentClass for public access./), not default for childrenSecurity
ACL Enforcement:
Protection Against Attacks:
Compatibility
Dependencies
@solid/oidc-rs,@solid/oidc-auth-manager)@solid/acl-check)node-solid-ws(v0.4.3) to support authorization callbacksnpm link solid-wsto test with modified node-solid-wsFiles Modified
node-solid-server:
lib/create-server.mjs- WebSocket authentication and authorizationtest/integration/authentication-oidc-test.mjs- WebSocket auth test suitetest/resources/accounts-scenario/alice/.acl-override- Public read for rootnode-solid-ws:
lib/server.js- Authorization callback supporttest/websockets.js- Authorization callback test suiteConfiguration
live: trueis setldp.tokenTypesSupported(defaults to['DPoP', 'Bearer'])