【问题标题】:Spring SockJs RequestHandler doesn't upgrade connection to 101Spring SockJs RequestHandler 不会将连接升级到 101
【发布时间】:2016-10-13 20:23:00
【问题描述】:

尽管 Spring 文档中没有描述这一点,但 websocket 连接应该会导致连接升级响应(101 状态)。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig<S extends ExpiringSession> extends AbstractSessionWebSocketMessageBrokerConfigurer<S>{

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/queue");

        config.setApplicationDestinationPrefixes("/mobile-server");

        config.setUserDestinationPrefix("/mobile-user");

    }

    @Override
    public void configureStompEndpoints(StompEndpointRegistry registry) {
        registry
            .addEndpoint("/ws")
            .setHandshakeHandler(new DefaultHandshakeHandler(new TomcatRequestUpgradeStrategy()))
            .setAllowedOrigins("*")
            .withSockJS()
            .setSessionCookieNeeded(false)
            ;
    }

}

但是,我得到一个 200 状态,其中包含由 TransportHandlingSockJsService 生成的“欢迎使用 SockJS”消息,而不是生成升级 AFAIK 的 WebSocketHttpRequestHandler

@Configuration
public class WebSocketSecurity extends AbstractSecurityWebSocketMessageBrokerConfigurer{

 @Override
 protected boolean sameOriginDisabled() {
    return true;
 }

    @Override
 protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
      messages
        .nullDestMatcher().permitAll()
        .simpSubscribeDestMatchers("/user/queue/errors").permitAll()
        .simpDestMatchers("/mobile-server/**").hasRole("ENDUSER")
        .simpSubscribeDestMatchers("/user/**", "/topic/**").hasRole("ENDUSER")
        .anyMessage().denyAll();
  }
}

当我将配置更改为

@Override
public void configureStompEndpoints(StompEndpointRegistry registry) {
    registry
        .addEndpoint("/ws")
        .setHandshakeHandler(new DefaultHandshakeHandler(new TomcatRequestUpgradeStrategy()))
        .setAllowedOrigins("*");
}

令我惊讶的是,调用 /ws 确实会导致连接升级 101。我很惊讶,因为文档和所有示例都统一使用 withSockJS() 并且任何 websocket 连接 AFAIK 的开始都是请求升级。

我可以选择通过连接到 /ws/websocket 来强制升级(也没有记录)。所以,我不确定什么是最好的。

有什么建议吗?

【问题讨论】:

    标签: spring-security spring-websocket spring-session


    【解决方案1】:

    这是预期的行为。这就是 SockJS 协议的工作原理: http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html。有一个初始的“问候”请求,然后客户端开始尝试一次传输一个。

    【讨论】:

    • 我建议在这方面添加文档。对于新手来说,这非常令人困惑。
    猜你喜欢
    • 2020-10-10
    • 2015-08-05
    • 2016-07-26
    • 2021-05-06
    • 2015-01-26
    • 2015-08-10
    • 2017-11-20
    • 1970-01-01
    • 2022-07-20
    相关资源
    最近更新 更多