为什么会话超时后websocket连接没有终止?

ct3nt3jp  于 2021-07-24  发布在  Java
关注(0)|答案(0)|浏览(309)

我的决定是:
我用 STOMP CONNECT frame header 验证而不是 cookie-based authentication 因为移动应用程序没有很好的 Cookie-based authentication 支持。
我用 X-Auth-Token 要获取的标题 Authentication 因为 WebSocket Protocol 不允许javascript更改 HTTP headers 在http握手期间。默认情况下,spring security使用 Cookie-based authentication spring安全中的身份验证非常简单。
httpsessionconfig.java文件

// see: https://docs.spring.io/spring-session/docs/current/reference/html5/#httpsession-rest
@Configuration
//// Override HttpSession's Filter, in this instance Spring Session is backed by Redis.
//@EnableRedisHttpSession
public class HttpSessionConfig {

//  // Default connection configuration, to localhost:6739.
//  @Bean
//  public LettuceConnectionFactory connectionFactory() {
//    return new LettuceConnectionFactory();
//  }

  // Tell Spring to use HTTP headers, X-Auth-Token.
  @Bean
  public HttpSessionIdResolver httpSessionIdResolver() {
    return HeaderHttpSessionIdResolver.xAuthToken();
  }
}

这个 STOMP CONNECT frame header 验证逻辑:
我明白了 String sessionId = ...X-Auth-Token 标题的值。
我明白了 Session session = ...sessionRepository.findById(sessionId) 我明白了 SecurityContextImpl securityContext = ...session.getAttribute("SPRING_SECURITY_CONTEXT") 我明白了 Authentication user = ...securityContext.getAuthentication() .
最后,我设置了 StompHeaderAccessor accessoraccessor.setUser(user) .
应用程序.yml

server.servlet.session.timeout: 1m

websocketconfig.java文件

@Configuration
// see: https://docs.spring.io/spring-session/docs/current/reference/html5/#websocket-usage
@EnableScheduling
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<Session> {

  private final SessionRepository<? extends Session> sessionRepository;

  public WebSocketConfig(SessionRepository<? extends Session> sessionRepository) {
    this.sessionRepository = sessionRepository;
  }

  // see: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#websocket-stomp-authentication-token-based
  @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);
        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
          String sessionId = accessor.getFirstNativeHeader("X-Auth-Token");
          Session session = sessionRepository.findById(sessionId);
          if (session != null) {
            SecurityContextImpl securityContext = session.getAttribute("SPRING_SECURITY_CONTEXT");
            Authentication user = securityContext.getAuthentication();
            accessor.setUser(user);
          }
        }
        return message;
      }
    });
  }

  @Override
  protected void configureStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/chat");
  }

  @Override
  public void configureMessageBroker(MessageBrokerRegistry registry) {
    registry.setApplicationDestinationPrefixes("/app");
    registry.enableSimpleBroker("/topic", "/queue");
    registry.setUserDestinationPrefix("/user");
  }

}

我的预期结果是:根据 Spring 会议的正式文件。如果设置 server.servlet.session.timeout: 1mapplication.yml 我的实际结果是:websocket连接没有终止,用户仍然订阅了 /topic/channel/{channelId} 用户仍然可以向 /app/channel/{channelId} .

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题