The way I solved the authentication problem was that in my preSend I set the authentication token from the headers that contain it:
public final class WebsocketAuthorizationInterceptorWebsocketAuthenticationInterceptor implements ChannelInterceptor { public static final String SIMP_USER_HEADER = "simpUser"; @SneakyThrows @Override public Message<?> preSend(Message<?> message, MessageChannel channel) { setAuthenticationIfPresent(message); return message; } private void setAuthenticationIfPresent(Message<?> message) { if (message instanceof GenericMessage<?> genericMessage && genericMessage.getHeaders().get(SIMP_USER_HEADER) instanceof PreAuthenticatedAuthenticationToken token) { SecurityContextHolder.getContext().setAuthentication(token); } } } and afterwards you can always access it anywhere (including the sessionConnectedEvent method) via SecurityContextHolder.getContext().getAuthentication()
Depending on where you are trying to access the Authenticated Principal, you might have to set SecurityContextHolder.MODE_INHERITABLETHREADLOCAL to allow child threads to access the Authentication Object that was set by the parent thread. For that just add this to any Configuration Bean:
@PostConstruct void setGlobalSecurityContext() { SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL); }