Spring Boot:用户连接到给定某种身份验证方法的套接字时生成主体

问题描述

我无法验证Websocket的前端。该应用程序应该实现一对一的聊天界面。我已经遵循了所有可以在网上找到的教程,但是还没有找到任何解决方案。

仅当浏览器中有一个cookie时,才能识别出正确的用户(该cookie是通过招摇方法触发时保存的),但是该服务器是为提供Android应用服务的,所以我正在寻找其他方式,最好是使用JWT令牌。如何从前端发送“标题”?我正在尝试使用javascript进行测试,但到目前为止还没有。

这是我到目前为止所拥有的:

@Configuration
@EnableWebSocketMessagebroker
public class WebSocketbrokerConfig implements WebSocketMessagebrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").setHandshakeHandler(new CustomHandshakeHandler()).setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessagebroker(MessagebrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app");
        registry.enableSimplebroker("/secured/user");
        registry.setUserDestinationPrefix("/secured/user");
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(new UserChatSubscriptionInterceptor());
    }
}
public class UserChatSubscriptionInterceptor implements ChannelInterceptor {

    @Override
    public Message<?> preSend(Message<?> message,MessageChannel channel) {
        StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);

        if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand())) {
            Principal userPrincipal = headerAccessor.getUser();
            if(!validateSubscription(userPrincipal,headerAccessor.getDestination()))
            {
                throw new IllegalArgumentException(String.format("You are %s but tried to subscribe to %s",userPrincipal == null ? null : userPrincipal.getName(),headerAccessor.getDestination()));
            }
        }
        return message;
    }

    private boolean validateSubscription(Principal principal,String topicDestination) {
        if (principal == null) {
            return false;
        }

        String user = principal.getName();
        String requestedUser = topicDestination.replace("/secured/user/","");
        requestedUser = requestedUser.replace("/queue/messages","");
        if(!requestedUser.equals(user)) {
            return false;
        }
        return true;
    }
}
@Configuration
class CustomHandshakeHandler extends DefaultHandshakeHandler {

    @Override
    protected Principal determineUser(
            ServerHttpRequest request,WebSocketHandler wsHandler,Map<String,Object> attributes
    ) {

        return new StompPrincipal(request.getPrincipal().getName());
    }
}
public class StompPrincipal implements Principal {

    private String name;

    public StompPrincipal(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "StompPrincipal[name="+name+"]";
    }
}
<html>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.0/sockjs.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>

  <script>

    const serverUrl = 'http://localhost:8080/ws';
    const ws = new SockJS(serverUrl);
    const stompClient = Stomp.over(ws);
    stompClient.connect({},function(frame) {

      stompClient.subscribe('/secured/user/2/queue/messages',(message) => {
        console.log(stompClient);
        console.log(message);
      }
      );
    });



  </script>

</html>

有没有一种方法可以在CustomHandshakeHandler中获取令牌并确定StompPrincipal(我猜即使是手动也可以)?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)