没有从 headers 得到 SPRING.SESSION.ID
Not getting SPRING.SESSION.ID from headers
我正在使用 spring session 和 AbstractSessionWebSocketMessageBrokerConfigurer 并尝试创建一个支持 Spring 安全和 Spring 的 STOMP Websocket Session。我似乎无法激活我的 session。我使用 webstomp-client 连接 (https://github.com/JSteunou/webstomp-client)
摘要SessionWebSocketMessageBrokerConfigurer 创建
@Bean
@SuppressWarnings("unchecked")
public SessionRepositoryMessageInterceptor<S> sessionRepositoryInterceptor() {
return new SessionRepositoryMessageInterceptor<S>(this.sessionRepository);
}
我作为 header 传递给连接事件和每条消息
SPRING.SESSION.ID:<My session id>
当我检查 SessionRepositoryMessageInterceptor 中的处理时,我看到它正在尝试通过 SimpMessageHeaderAccessor 检索 session id,期望 header 包含 object header键下的simpSession属性。
Map<String, Object> sessionHeaders = SimpMessageHeaderAccessor
.getSessionAttributes(message.getHeaders());
String sessionId = sessionHeaders == null ? null
: (String) sessionHeaders.get(SPRING_SESSION_ID_ATTR_NAME);
SimpMessageHeaderAccessor 似乎期望的所有属性都没有出现在 stomp 客户端中,只是似乎属于不同的协议。
如何在 Stomp、Spring WebSocket、Spring 安全和 Spring Session 下激活 session?或者更具体地说:
- 为什么 SessionRepositoryMessageInterceptor 使用 SimpleHeaderAccessor 而不是 StompHeaderAcessor?
- 我需要从 javascript 客户端传递什么 header 来创建 session(假设我通过传统登录收到 session id)?
我不知道问题出在哪里,但我可以解释一些事情来帮助您调试问题。
Spring 支持 WebSocket-scoped 属性。只要 session 存在,这些属性就一直存在。 SessionRepositoryMessageInterceptor 作为 HandshakeInterceptor,挂接到初始 HTTP 握手请求并将 SPRING.SESSION.ID 保存为 WebSocket-scoped 属性。然后在握手之后,当 STOMP 消息开始流动时,它会拦截每个传入的消息,并检索 websocket 属性中的 SPRING.SESSION.ID。所以我不确定您为什么要将 SPRING.SESSION.ID 作为 header 传递。正如我刚刚解释并与 WebSocket session.
相关联的那样,这一切都已为您管理好
关于SimpHeaderAccessor vs StompHeaderAcessor的问题,前者是一个更通用的版本。只要它能为您提供足够的信息,使用它就没有错。在这种情况下 Spring Session 不关心 STOMP 的具体细节。
我不明白你的第二个问题,即需要从 javascript 客户端传递什么 header 来创建 session。只要 HTTP 握手是在同一个 HTTP session 中进行的,它就应该可以正常工作。这里与您执行任何 HTTP 调用的方式没有什么不同。
我正在使用 spring session 和 AbstractSessionWebSocketMessageBrokerConfigurer 并尝试创建一个支持 Spring 安全和 Spring 的 STOMP Websocket Session。我似乎无法激活我的 session。我使用 webstomp-client 连接 (https://github.com/JSteunou/webstomp-client)
摘要SessionWebSocketMessageBrokerConfigurer 创建
@Bean
@SuppressWarnings("unchecked")
public SessionRepositoryMessageInterceptor<S> sessionRepositoryInterceptor() {
return new SessionRepositoryMessageInterceptor<S>(this.sessionRepository);
}
我作为 header 传递给连接事件和每条消息
SPRING.SESSION.ID:<My session id>
当我检查 SessionRepositoryMessageInterceptor 中的处理时,我看到它正在尝试通过 SimpMessageHeaderAccessor 检索 session id,期望 header 包含 object header键下的simpSession属性。
Map<String, Object> sessionHeaders = SimpMessageHeaderAccessor
.getSessionAttributes(message.getHeaders());
String sessionId = sessionHeaders == null ? null
: (String) sessionHeaders.get(SPRING_SESSION_ID_ATTR_NAME);
SimpMessageHeaderAccessor 似乎期望的所有属性都没有出现在 stomp 客户端中,只是似乎属于不同的协议。
如何在 Stomp、Spring WebSocket、Spring 安全和 Spring Session 下激活 session?或者更具体地说:
- 为什么 SessionRepositoryMessageInterceptor 使用 SimpleHeaderAccessor 而不是 StompHeaderAcessor?
- 我需要从 javascript 客户端传递什么 header 来创建 session(假设我通过传统登录收到 session id)?
我不知道问题出在哪里,但我可以解释一些事情来帮助您调试问题。
Spring 支持 WebSocket-scoped 属性。只要 session 存在,这些属性就一直存在。 SessionRepositoryMessageInterceptor 作为 HandshakeInterceptor,挂接到初始 HTTP 握手请求并将 SPRING.SESSION.ID 保存为 WebSocket-scoped 属性。然后在握手之后,当 STOMP 消息开始流动时,它会拦截每个传入的消息,并检索 websocket 属性中的 SPRING.SESSION.ID。所以我不确定您为什么要将 SPRING.SESSION.ID 作为 header 传递。正如我刚刚解释并与 WebSocket session.
相关联的那样,这一切都已为您管理好关于SimpHeaderAccessor vs StompHeaderAcessor的问题,前者是一个更通用的版本。只要它能为您提供足够的信息,使用它就没有错。在这种情况下 Spring Session 不关心 STOMP 的具体细节。
我不明白你的第二个问题,即需要从 javascript 客户端传递什么 header 来创建 session。只要 HTTP 握手是在同一个 HTTP session 中进行的,它就应该可以正常工作。这里与您执行任何 HTTP 调用的方式没有什么不同。