Ina*_*cio 6 stomp redis spring-boot spring-websocket spring-session
我正在构建一个小型 websocket 项目并由 JWT 令牌机制保护,我想将 websocket 会话存储在 redis 而不是本地内存中。
@Override
protected void configureStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/hello")
.addInterceptors(new HttpSessionHandshakeInterceptor() {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
attributes.put("sessionId", session.getId());
}
return true;
}
})
.withSockJS()
.setSessionCookieNeeded(true);
}
Run Code Online (Sandbox Code Playgroud)
我在我的 redis 配置中使用 @EnableRedisHttpSession 并且上面的源代码安全地将 http 会话存储在 redis 中,但即使我刷新了我的 redis 数据库,我仍然可以向我连接的客户端发送和接收我的消息。
我的猜测是 HttpSession 与 WebSocket 会话不同。如果您使用基于令牌的身份验证,我应该如何“智能地”要求 spring 在 redis 中存储和维护与 websocket 相关的会话?
更新 1
StompHeaderAccessor accessor =
MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
List<String> tokenList = accessor.getNativeHeader("username");
accessor.removeHeader("username");
String username = null;
if (tokenList != null && tokenList.size() > 0) {
username = tokenList.get(0);
}
AuthenticationToken authToken = new AuthenticationToken(username);
SecurityContextHolder.getContext().setAuthentication(authToken);
switch(accessor.getCommand()) {
case CONNECT:
Principal auth = username == null ? null : authToken;
accessor.setUser(auth);
return MessageBuilder.createMessage(message.getPayload(), accessor.getMessageHeaders());
case CONNECTED:
System.out.println("Stomp connected");
break;
case DISCONNECT:
System.out.println("Stomp disconnected");
break;
case SEND:
break;
default:
break;
}
return message;
Run Code Online (Sandbox Code Playgroud)
更新 2
我认为 STOMP 上的 Websocket 依赖于 SimpSessionId 而不是在握手拦截器期间创建的 HttpSession。
StompHeaderAccessor [headers={simpMessageType=MESSAGE, stompCommand=SEND, nativeHeaders={username=[*******], destination=[/app/feed], content-length=[81]}, simpSessionAttributes={SPRING.SESSION.ID=187912de-a875-45ef-995a-7723fd8715c8}, simpHeartbeat=[J@6e9173e4, simpUser=***.AuthenticationToken@1767840c: Principal: *******; Credentials: [PROTECTED]; Authenticated: true; Details: null; Not granted any authorities, simpSessionId=d686qam8, simpDestination=/app/feed}]
Run Code Online (Sandbox Code Playgroud)
更新 3
SimpUserRegistry说这是“当前连接用户的注册表”。也许这就是答案?
更新 4
我正在使用 RabbitMQ。这是否意味着我所做的完全没有用?
| 归档时间: |
|
| 查看次数: |
1679 次 |
| 最近记录: |