当前位置 博文首页 > 无限迭代中......:Web Socket/Stomp——整合Spring Session【He

    无限迭代中......:Web Socket/Stomp——整合Spring Session【He

    作者:[db:作者] 时间:2021-07-19 19:22

    官方文档

    https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#websocket-stomp-authentication-token-based?

    解决方案

    方法一:

    参考:org.springframework.session.web.socket.server.SessionRepositoryMessageInterceptor、org.springframework.session.web.socket.config.annotation.AbstractSessionWebSocketMessageBrokerConfigurer

    /**
     * @author ShenTuZhiGang
     * @version 1.0.0
     * @date 2020-04-12 13:10
     */
    @Configuration
    @EnableWebSocket
    @EnableWebSocketMessageBroker
    @Order(Ordered.HIGHEST_PRECEDENCE + 99)
    public class CustomWebSocketConfig<S extends Session> implements WebSocketMessageBrokerConfigurer {
    
        private final SessionRepository<S> sessionRepository;
    
        public CustomWebSocketConfig(SessionRepository<S> sessionRepository) {
            Assert.notNull(sessionRepository, "sessionRepository cannot be null");
            this.sessionRepository = sessionRepository;
        }
    
        @Override
        public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
            stompEndpointRegistry.addEndpoint("/ws/endpointChat")
                    .setAllowedOrigins("*")
                    .withSockJS();
        }
    
        @Override
        public void configureClientInboundChannel(ChannelRegistration registration) {
            registration.interceptors(new ChannelInterceptor() {
                @Override
                public Message<?> preSend(Message<?> message, MessageChannel channel) {
                    StompHeaderAccessor accessor =
                            MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
                    assert accessor != null;
                    String sessionId = accessor.getFirstNativeHeader("X-Auth-Token");
                    if (sessionId != null) {
                        S session = sessionRepository.findById(sessionId);
                        if(session != null){
                            // update the last accessed time
                            session.setLastAccessedTime(Instant.now());
                            sessionRepository.save(session);
                            if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                                SecurityContext context = session.getAttribute(WebConstants.SPRING_SECURITY_CONTEXT);
                                Authentication user =  context.getAuthentication() ; // access authentication header(s)
                                accessor.setUser(user);
                            }
                        }
                    }
                    return message;
                }
            });
        }
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
            registry.enableSimpleBroker("/queue", "/topic");
        }
    
    }

    方法二:

    Springboot http session支持分布式;同时支持 cookie 和 header 传递;websocket 连接 共享 http session?

    参考文章

    Springboot http session支持分布式;同时支持 cookie 和 header 传递;websocket 连接 共享 http session?

    Spring Websocket/STOMP 和SpringSession整合 初步

    ?

    cs