0

When processing a websocket request in a controller

SecurityContextHolder.getContext().getAuthentication() 

returns null. But I need to know which user is making the request.

What was tried so far:

  • Google pointed me towards solutions implementing ChannelInterceptor, but in all its methods getAuthentication() also returns null. So there is nothing to carry over somehow. How to retrieve the current logged in user in a websocket controller

  • In an implementation of onApplicationEvent(SessionSubscribeEvent) or onApplicationEvent(SessionConnectEvent) on the websocket controller the getAuthentication() returns null.

  • I found that in an implementation of HandshakeInterceptor the getAuthentication() returns a Principal. What can that information be made available in an STOMP Websocket controller method? The methods do not have access to a thread bound request. (No thread-bound request found exception) when using:

    RequestContextHolder.currentRequestAttributes().getSessionId()

    And the sessionId that can be injected (8 characters) does not match the session id of the normal requests (32 characters): How to get Session Id in Spring WebSocketStompClient?

    @Header("simpSessionId") String sessionId

tbeernot
  • 2,473
  • 4
  • 24
  • 31

1 Answers1

0

The controller can listen to SessionConnectEvents and SessionDisconnectEvents which contains the 8 character sessionId:

    @EventListener
    public void handleWebSocketConnectListener(SessionConnectEvent event) {
        String sessionId = event.getMessage().getHeaders().get("simpSessionId", String.class);
        Principal principal = event.getUser();
        if (LOG.isInfoEnabled()) LOG.info("Session connect " + sessionId + ": " + principal);
        sessions.put(sessionId, principal);
    }

    @EventListener
    public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
        String sessionId = event.getSessionId();
        if (LOG.isInfoEnabled()) LOG.info("Session disconnect " + sessionId);
        sessions.remove(sessionId);
    }

And the message handling method can get the 8 character sessionId injected:

@MessageMapping("/...")
    public void browserToBackend(Message message, @Header("simpSessionId") String sessionId) throws Exception {
        command.principal = sessions.get(sessionId);
        ...
tbeernot
  • 2,473
  • 4
  • 24
  • 31