WebSocket握手期间出错:意外的响应代码:200在Jhipster应用程序中

问题描述

我试图在使用Java spring和Angular 8构建的现有Jhipster应用程序中连接到websocket。在创建项目时,我没有选择websocket选项,现在需要实现项目中的websockets。我从“ https://www.jhipster.tech/using-websockets/”获得了帮助,并尝试实现相同的解决方案,但我收到了握手失败消息。 我在websockets中使用STOMP和sockJS。 请让我知道握手失败的原因。

这是websocket configuration.java文件


import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessagebrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessagebroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessagebrokerConfigurer;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

import hr.nic.vc.security.AuthoritiesConstants;

import java.security.Principal;

import org.springframework.http.server.*;

import java.util.*;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.*;
import org.springframework.messaging.simp.config.MessagebrokerRegistry;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.*;
import org.springframework.web.socket.server.HandshakeInterceptor;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

@Configuration
@EnableWebSocketMessagebroker
public class WebsocketConfiguration implements WebSocketMessagebrokerConfigurer {

  @Override
  public void configureMessagebroker(MessagebrokerRegistry config)
  {
    config.enableSimplebroker("/topic");
    //config.setApplicationDestinationPrefixes("/app");
  }

  @Override
  public void registerStompEndpoints(StompEndpointRegistry
   registry) {
    registry.addEndpoint("/websocket/blog").setHandshakeHandler(defaultHandshakeHandler())
        .setAllowedOrigins("*").withSockJS();
  }
  
  @Bean
  public HandshakeInterceptor httpSessionHandshakeInterceptor() {
      return new HandshakeInterceptor() {

          @Override
          public boolean beforeHandshake(ServerHttpRequest request,ServerHttpResponse response,WebSocketHandler wsHandler,Map<String,Object> attributes) throws Exception {
              if (request instanceof ServletServerHttpRequest) {
                  ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                  attributes.put(IP_ADDRESS,servletRequest.getRemoteAddress());
              }
              return true;
          }

          @Override
          public void afterHandshake(ServerHttpRequest request,Exception exception) {

          }
      };
  }

  private DefaultHandshakeHandler defaultHandshakeHandler() {
      return new DefaultHandshakeHandler() {
          @Override
          protected Principal determineUser(ServerHttpRequest request,Object> attributes) {
              Principal principal = request.getPrincipal();
              if (principal == null) {
                  Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
                  authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
                  principal = new AnonymousAuthenticationToken("WebsocketConfiguration","anonymous",authorities);
              }
              return principal;
          }
      };
  }
  
}

这是websocket安全文件

public class WebsocketSecurityConfiguration extends AbstractSecurityWebSocketMessagebrokerConfigurer {

    @Override
      protected void configureInbound(MessageSecurityMetadataSourceRegistry messages)
      {
        messages.nullDestMatcher().authenticated().simpDestMatchers("/topic/blog")
            .authenticated()
            // matches any destination that starts with /topic/
            // (i.e. cannot send messages directly to /topic/)
            // (i.e. can’t subscribe to /topic/messages/* to get messages which is sent to
            // /topic/messages-user)
            .simpDestMatchers("/topic/**").authenticated();
            // message types other than MESSAGE and SUBSCRIBE
            //.simpTypeMatchers(SimpMessageType.MESSAGE,SimpMessageType.SUBSCRIBE).denyAll()
            // catch all
            //.anyMessage().denyAll();
      }
    /**
     * disables CSRF for Websockets.
     */
    @Override
    protected boolean sameOrigindisabled() {
        return true;
    }
}

这是在验证身份后用于连接Websocket的connect方法

connect():void {
    console.log("connect called"); //eslint-disable-line
    // build absolute path,websocket doesn't fail during deploying with a context path
    let url = '/websocket/blog';
    url = this.location.prepareExternalUrl(url);
    const authToken = this.authServerProvider.getToken();
    if (authToken) {
      url += '?access_token=' + authToken;
    }
    const socket = new SockJS(url);
    this.stompClient = Stomp.over(socket);
    const headers = {};
    this.stompClient.connect(headers,() => {
        console.log("this is inside stompclient connect connect"); //eslint-disable-line
      this.stompClient.subscribe('/topic/blog',data => {
          console.log("This inside subscription"); //eslint-disable-line
        this.listenerObserver.next(JSON.parse(data.body));
      });
    });
  }
}

授权令牌以正确的值传递。因此,授权中没有错误。 如果需要其他任何条件,请告诉我。 我在这一点上停留了很长时间。

错误

WebSocket connection to 'ws://localhost:8080/websocket/blog/587/mklduqvp/websocket?access_token=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJoYXJkZWVwc2h1a2xhMDhAbmljLmluIiwiYXV0aCI6IlJPTEVfRU1QTE9ZRUUiLCJleHAiOjE2MDUyNDUwNjd9.DJ2HITaVAiaphd2yg3yPAiLrLI4n8MjszjBasC3zOHrC-73mFdltDPEYHihY16VzPv0rh6EYLj84zCBv37TDNA' Failed: Error during WebSocket handshake: Unexpected response code: 200

解决方法

您可以在DefaultHandshakeHandler中尝试为@Bean注释并设置为public。

@Bean
public DefaultHandshakeHandler defaultHandshakeHandler() {