WebSocket Interceptors & Security
Relevant source files
The following files were used as context for generating this wiki page:
- src/main/java/org/example/coding_convention/config/interceptor/JwtHandshakeInterceptor.java
- src/main/java/org/example/coding_convention/config/interceptor/AuthChannelInterceptor.java
- src/main/java/org/example/coding_convention/config/WebSocketConfig.java
- src/main/java/org/example/coding_convention/config/SecurityConfig.java
- src/main/java/org/example/coding_convention/websocket/WebSocketController.java
- src/main/java/org/example/coding_convention/utils/JwtUtil.java
- README.md
Introduction
The PhanesEditor project utilizes a robust WebSocket security architecture to facilitate real-time collaboration features such as chat and code synchronization. This system ensures that only authorized users—specifically project members—can participate in real-time communication. Security is enforced through a two-stage interception process: a handshake interceptor for the initial connection and a channel interceptor for subsequent STOMP message traffic.
The implementation separates standard HTTP CRUD security from WebSocket real-time communication while maintaining a unified authentication source via JSON Web Tokens (JWT). This architecture prevents unauthorized access to project-specific channels and ensures that every message broadcast is associated with a verified identity.
Sources: README.md:14-35, src/main/java/org/example/coding_convention/config/WebSocketConfig.java:13-20
WebSocket Infrastructure Components
The WebSocket system is built upon the Spring Framework's STOMP over WebSocket support. The configuration defines how clients connect to the server and how messages are routed to specific destinations.
Connection and Routing Configuration
The central configuration class WebSocketConfig enables the message broker and registers the primary endpoint used for initiating connections.
- Endpoint:
/websocketis the entry point for WebSocket connections. - Allowed Origins: Specific domains are whitelisted, including
https://www.gomorebi.kro.krandhttp://localhost:5173. - Message Broker: Uses a simple broker with the
/topicprefix for outgoing broadcasts and/appfor incoming application-bound messages.
Sources: src/main/java/org/example/coding_convention/config/WebSocketConfig.java:21-38
Architectural Overview Diagram
The following diagram illustrates the flow from initial handshake to message processing.
This flow depicts the lifecycle of a WebSocket connection and the security checkpoints it must pass.
Sources: src/main/java/org/example/coding_convention/config/WebSocketConfig.java, src/main/java/org/example/coding_convention/config/interceptor/JwtHandshakeInterceptor.java
Authentication and Interceptors
Security is implemented using two distinct interceptors that handle different phases of the WebSocket lifecycle.
Stage 1: JwtHandshakeInterceptor
The JwtHandshakeInterceptor is executed during the initial HTTP Upgrade request (handshake). Its primary role is to extract the JWT from the request cookies and verify the user's identity before the WebSocket connection is even established.
- JWT Extraction: It searches for a cookie named
SJB_AT. - Authentication Object: If the token is valid, it builds a
UsernamePasswordAuthenticationTokencontaining the user's ID, email, and nickname. - Attribute Injection: The resulting
Authenticationobject is stored in the WebSocket session attributes under the key"auth".
Sources: src/main/java/org/example/coding_convention/config/interceptor/JwtHandshakeInterceptor.java:22-60
Stage 2: AuthChannelInterceptor
Once the connection is established, the AuthChannelInterceptor monitors incoming STOMP messages. This interceptor ensures that the authentication context established during the handshake is correctly mapped to each STOMP session.
- STOMP CONNECT Handling: When a
CONNECTcommand is received, it retrieves theAuthenticationobject from the session attributes and sets it as the user for the currentStompHeaderAccessor. - User Persistence: This allows controllers to access the user's identity via the
Principalobject in message mapping methods.
Sources: src/main/java/org/example/coding_convention/config/interceptor/AuthChannelInterceptor.java:22-38
WebSocket Message Handling
The WebSocketController manages the logic for real-time features. It relies on the security context provided by the interceptors to identify senders and route messages to specific rooms.
| Functionality | Message Mapping | Destination (Topic) | Payload Type |
|---|---|---|---|
| Chat Messaging | /chat/{roomId} | /topic/chat/{roomId} | ChatMessageDto |
| Code Editor | /editor/{roomId} | /topic/editor/{roomId} | EditorDto.Code |
Sources: src/main/java/org/example/coding_convention/websocket/WebSocketController.java:18-35
Sequence Diagram: Chat Message Flow
The following sequence diagram shows how a message is secured and broadcast.
This diagram illustrates how the principal name is extracted from the secured session to label chat messages before broadcasting.
Sources: src/main/java/org/example/coding_convention/websocket/WebSocketController.java:24-28, src/main/java/org/example/coding_convention/config/interceptor/AuthChannelInterceptor.java:22-35
Security Configuration Summary
The project maintains a strict security profile for WebSockets, separate from the standard HTTP filter chain but sharing the same token utility.
- Token Management: Tokens are generated and validated using
JwtUtil, with an expiration of approximately 4 hours (240 minutes). - CORS Settings: The
SecurityConfigandWebSocketConfigboth define allowed origins to prevent Cross-Site WebSocket Hijacking (CSWSH). - Access Control: The README indicates that all real-time functions are gated by project membership, verified during the connection and message processing phases.
Sources: src/main/java/org/example/coding_convention/utils/JwtUtil.java:18-20, src/main/java/org/example/coding_convention/config/SecurityConfig.java:55-65, README.md:52-60
Conclusion
WebSocket Interceptors and Security in PhanesEditor provide a multi-layered defense mechanism. By verifying JWTs during the initial handshake and maintaining user context through STOMP channel interceptors, the system ensures that collaborative features like real-time code editing and chatting are restricted to authenticated project members. This architecture provides a seamless transition from HTTP-based authentication to stateful WebSocket communication.