Spring websocket没有主体

标签 spring websocket stomp anonymous principal

我正在尝试实现一个简单的 websockets 应用程序,该应用程序可以将消息从一个端点发送到在其他地方建立的指定 session 。到目前为止,我已经能够使用注释 @SendToUser() 以便客户端订阅 channel (如本问题中所述: Spring Websockets @SendToUser without login? )

但是,我现在想要创建一个单独的端点,在调用该端点时,它会查找与传递到此端点的数据关联的用户,并向该用户发送有关此数据的消息。

但是,我无法准确确定如何实现它,以便我可以调用 SimpMessagingTemplate ConvertAndSendToUser() 命令,因为我的用户没有主体(我没有使用 Spring Security)。

我已经能够从传递到 @MessageMapping 端点的 MessageHeaders 中获取 simpSessionId,但现在我不知道如何使用 simpSessionId 从应用程序的不同部分发送信息。

我已经做了一些研究,涉及覆盖 DefaultHandshakeHandler 的 certainUser() 方法,并在成功的 websocket 握手后将随机生成的 UUID 作为用户名分配给用户(如此问题的答案中所述: How to reply to unauthenticated user in Spring 4 STOMP over WebSocket configuration? ),但是由于出现的主体为空,我不确定如何正确生成主体并将其分配给主体以供应用程序使用。

我基本上需要能够拥有匿名用户,并在他们创建 Websocket 连接后从应用程序的不同部分向他们发送消息。

最佳答案

因此,对于面临类似问题的其他人,我实现了自己的 Primary 类:

package hello;

import java.security.Principal;
import java.util.Objects;

public class AnonymousPrincipal implements Principal {

    private String name;

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object another) {
        if (!(another instanceof Principal))
            return false;

        Principal principal = (Principal) another;
        return principal.getName() == this.name;

    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

然后,我实现了我自己的 DefaultHandshakeHandler 版本:

package hello;

import java.security.Principal;
import java.util.Map;
import java.util.UUID;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

public class CustomHandshakeHandler extends DefaultHandshakeHandler {

    @Override
    protected Principal determineUser(ServerHttpRequest request,
            WebSocketHandler wsHandler, Map<String, Object> attributes) {
        Principal principal = request.getPrincipal();           

        if (principal == null) {
            principal = new AnonymousPrincipal();

            String uniqueName = UUID.randomUUID().toString();

            ((AnonymousPrincipal) principal).setName(uniqueName);
        }

        return principal;

    }

}

现在,当握手发生时,Websocket session 会获取分配给它的主体,因此如果用户是匿名的,他们会分配一个匿名主体,这将允许我存储他们的名称(生成的 UUID)以供以后在网络的其他部分使用应用程序。

关于Spring websocket没有主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43218623/

相关文章:

ejabberd 的 WebSocket 支持

ajax - 如何在不刷新页面的情况下将新的 HTML 数据从服务器推送到浏览器

swift - 收到用于连接到网络套接字的 "Invalid Sec-WebSocket-Accept response"

c# - Apollo Stomp ActiveMQ 创建无效的临时目的地名称

java - Spring Security + 根据用户名限制用户

java - Spring 3 中的自定义 Autowire 候选 bean

java - 为什么我在启动 springdata Rest api 时遇到异常

java - JCache 的 Spymemcached 的完全限定名称

python - gevent-socketio 不使用我的 @app.route 端点用于 socketio

java - 无法在 JMS 中正确创建消息选择器