繁体   English   中英

在spring中使用websocket时出错“忽略消息,没有可用的主体信息”

[英]Error “Ignoring message, no principal info available” when using websocket in spring

在我的系统中,我使用自定义登录机制,因此tomcat和spring不知道经过身份验证的用户信息。 当我订阅端点时:

stompClient.subscribe("/user/queue/position-updates", function(message) {...});

春天会投诉“忽略消息,没有可用的主要信息”。 我追溯到代码,并发现spring将尝试从DefaultUserDestinationResolver类中的会话中获取原理信息,但是不会获取任何内容,因此会给出错误消息。

我的问题是:spring websocket是否依赖于tomcat或spring的安全机制? 我可以手动将经过身份验证的用户信息设置为http会话原理吗?

谢谢!

WebSocketSession中的用户来自会话开始时的HttpServletRequest.getUserPrincipal()(即握手请求)。 您可以包装HTTP请求(例如,从过滤器中)并覆盖返回用户的方法,也可以扩展DefaultHandshakeHandler(请参阅determineUser protected方法)。 Java和XML配置都提供了一种配置自定义HandshakeHandler的方法。

你可以像这样实现HandshakeHandler。

public class HandshakeHandler extends DefaultHandshakeHandler {
Logger logger = (Logger) LoggerFactory.getLogger(HandshakeHandler.class);
@Override
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
    Principal principal = request.getPrincipal();

    if(principal==null)
    {
        ServletServerHttpRequest req= (ServletServerHttpRequest)request;
        HttpSession session = req.getServletRequest().getSession();
        final User user = (User) session.getAttribute("user");
        principal=new Principal() {
            @Override
            public String getName() {
                return user!=null?user.getId():"";
            }
        };
    }
    logger.debug("principal:{}",principal);
    return principal;
}

}

然后在你的xml中声明它。

<bean id="handshakeHandler" class="x.x.x.HandshakeHandler"/>

<websocket:message-broker application-destination-prefix="/app">
  <websocket:stomp-endpoint path="/ws">
      <websocket:handshake-handler ref="handshakeHandler"/>
      <websocket:sockjs/>
  </websocket:stomp-endpoint>
  <websocket:simple-broker prefix="/topic, /queue"/>
</websocket:message-broker>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM