I’m using a custom WebSocketChannelInterceptor (implements ChannelInterceptor) to handle authentication during the CONNECT STOMP command. The interceptor extracts and validates a JWT token from the Authorization header like this:
@Override
public Message<?> preSend(@NonNull Message<?> message, @NonNull MessageChannel channel) {
var accessor = StompHeaderAccessor.wrap(message);
StompCommand command = accessor.getCommand();
if (command == null) {
return null;
}
return switch (command) {
case CONNECT -> handleConnect(message, accessor);
case SEND -> handleSend(message, accessor);
default -> message;
};
}
private Message<?> handleConnect(Message<?> message, StompHeaderAccessor accessor) {
String authorizationHeader = accessor.getFirstNativeHeader(HttpHeaders.AUTHORIZATION);
if (authorizationHeader == null || !authorizationHeader.startsWith(JwtService.BEARER_PREFIX)) {
throw new MessageHandlingException(message, "Missing or invalid authorization header");
}
String token = authorizationHeader.substring(JwtService.BEARER_PREFIX.length()).trim();
try {
var jwtAuthToken = new JwtAuthenticationToken(token);
authManager.authenticate(jwtAuthToken);
return message;
} catch (BadCredentialsException e) {
throw new MessageHandlingException(message, e.getMessage());
} catch (RuntimeException e) {
throw new MessageHandlingException(message, "Internal server error");
}
}
My question is: How can I access the authenticated user's Principal inside the SessionConnectedEvent handler?
@Slf4j
@Component
@RequiredArgsConstructor
public class WebSocketEventListener {
@EventListener
public void sessionConnectedEvent(SessionConnectedEvent event) {
// How to get Principal here?
}
}
I’m not interested in SessionConnectEvent — I specifically want to get the user from SessionConnectedEvent after the handshake and connection are completed.
Thanks in advance!
I've tried many different approaches, but none of them worked for my case. The token is sent during the initial WebSocket connection using STOMP headers like this:
const client = new Client({
brokerURL: 'ws://localhost:8080/ws',
connectHeaders: {
"Authorization": `Bearer ${accessToken}`,
},
onStompError: await onStompError,
onConnect: () => {
console.log("Successfully connected");
},
debug: console.debug
});