Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何编写用于连接OAuth 2.0安全Spring WebSocket API的JavaScript客户端?_Javascript_Spring Boot_Websocket_Oauth 2.0_Spring Websocket - Fatal编程技术网

如何编写用于连接OAuth 2.0安全Spring WebSocket API的JavaScript客户端?

如何编写用于连接OAuth 2.0安全Spring WebSocket API的JavaScript客户端?,javascript,spring-boot,websocket,oauth-2.0,spring-websocket,Javascript,Spring Boot,Websocket,Oauth 2.0,Spring Websocket,我需要使用spring创建一个Websocket服务器,这可以通过使用下面的代码轻松完成 @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(

我需要使用spring创建一个Websocket服务器,这可以通过使用下面的代码轻松完成

 @Configuration
 @EnableWebSocket
 public class WebSocketConfig implements WebSocketConfigurer {
 @Override
 public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
 registry.addHandler(new SocketHandler(), "/poll");
 registry.addHandler(new SocketPushHandler(), "/push");
 }

 }
其中,SocketHandler和SocketPushHandler是websocket端点的处理程序类

在这一切正常之前,我们能够运行服务器并使用普通的
socket=newwebsocket(websocketUrl)
javascript代码连接到端点

现在我们需要在API端点上实现OAuth 2.0安全性,这可以通过导入一些Spring安全依赖项轻松实现\

现在,最困难的部分是编写客户端来连接安全端点,方法是将Oauth
Authorization beaer
作为头的一部分传递。 从文档中我们知道,我们不能向Web套接字端点发送头

因此,根据此链接中的信息,我创建了一个API网关
/open ws Request type GET
,客户端将连接到该网关并向其发送授权头,服务器端内部的该端点将打开一个WebSocket客户端连接,将头传递为
javax.WebSocket.WebSocketContainer
支持带有自定义标题的websocket客户端

现在,我的javascript首先对网关端点进行GET ajax调用,并在成功时发出新的websocket请求

下面是模拟网关的SpringAPI

@RequestMapping(value = "/open-ws", method = RequestMethod.GET)
public void getOperatorTokenDefinition(@RequestHeader(value = HttpHeaders.AUTHORIZATION) String bearerToken,
                @RequestHeader(value = "websocketURL") String websocketURL,
                HttpServletRequest acquireTokenServletRequest, HttpServletResponse response) {

    webSocketClient.connecttoserver(websocketURL, acquireTokenServletRequest.getRemoteHost(), bearerToken, response);
    // ResponseEntity<String> responseEntity = new ResponseEntity<>("connected", HttpStatus.OK);
     }
因此,问题是这是连接Oauth 2.0 Websocket的正确方法,如果是,如何处理上述错误,如果否,如何将头发送到授权端点。

注意:不使用Stomp,因为我们还没有确认实际的客户端(即UI)是否允许/拥有Stomp JS

    @Component
public class WebSocketClient {

    private Session client;

public void connecttoserver(String websocketURL,String host,String bearerAccessToken, HttpServletResponse response) {

    final AtomicReference<String> message = new AtomicReference<>();
    Endpoint endpoint = new Endpoint() {
        @Override
        public void onOpen(Session session, EndpointConfig config) {
             System.out.println("WSS OPEN!!!!!");
  try (OutputStream output = response.getOutputStream()) {
            output.write(session.getId());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


         }
    };

    ClientEndpointConfig.Configurator configurator = new ClientEndpointConfig.Configurator() {

        @Override
        public void beforeRequest(Map<String, List<String>> headers) {

            List<String> connection = new ArrayList<>(1);
            connection.add("Upgrade");
            List<String> origin = new ArrayList<>(1);
            origin.add(originURL);
            List<String> upgradeWebsocket = new ArrayList<>(1);
            upgradeWebsocket.add("WebSocket");
            List<String> host = new ArrayList<>(1);
            host.add(websocketURL);
            List<String> contenttype = new ArrayList<>(1);
            contenttype.add("application/json");
            List<String> authorization = new ArrayList<>(1);
            authorization.add("Bearer " + bearerAccessToken);
            List<String> tenantId = new ArrayList<>(1);
            tenantId.add(tenantID);
            List<String> key = new ArrayList<>(1);
            key.add("HcFOxrSD89ya65X2qMF9lQ==");
            List<String> version = new ArrayList<>(1);
            version.add("13");

            headers.put("Connection", connection);
            headers.put("Upgrade", upgradeWebsocket);
            headers.put("Host", host);
            headers.put("Origin", origin);
            // headers.put("Content-Type", contenttype);
            headers.put("Authorization", authorization);
            headers.put("Sec-WebSocket-Key", key);
            headers.put("Sec-WebSocket-Version", version);
        }

    };


    ClientEndpointConfig clientConfig = ClientEndpointConfig.Builder.create().configurator(configurator).build();

    WebSocketContainer container = ContainerProvider.getWebSocketContainer();
    try {

        // if (!this.client.isOpen())
        this.client = container.connectToServer(endpoint, clientConfig, URI.create(websocketURL));


        client.addMessageHandler(new MessageHandler.Whole<String>() {

            @Override
            public void onMessage(String response) {
                // TODO Auto-generated method stub
                message.set(response);
                // System.out.println("response>>>>>>>>>>>>>>>>>>> "+response.toString());// this dosent work
            }
        });

        System.out.println("Response--------------------------------->" + message.get());
        // client.close();

    } catch (DeploymentException | IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }

    }
}
      $(document).ready(function(){
        $("#Websocketconnect").click(function(){
            $.ajax({
                type: 'GET',
                url: hostUrl.value,
                headers: {
                "Authorization":websocketToken.value,
                "websocketURL":websocketUrl.value,
                "Content-type":"text/plain"
                },
                success: function(result){
                $("#readystatus").value = result;
                webSocketCycleEvent(websocketUrl.value);
            }});
        });
    });


    function webSocketCycleEvent(websocketUrl){

      socket = new WebSocket(websocketUrl);
      socket.onerror = function(error) {
        console.log('WebSocket Error: ' + error);
      };


      // Show a connected message when the WebSocket is opened.
      socket.onopen = function(event) {
        socketStatus.innerHTML = 'Connected to: ' + websocketUrl;
        socketStatus.className = 'open';
      };
      socket.onmessage = function(event) {
        var message = event.data;
        messagesList.innerHTML += '<li class="received"><span>Received:</span>' +
                                   message + '</li>';
      };

   socket.onclose = function(event) {
        socketStatus.innerHTML = 'Disconnected from WebSocket.';
        socketStatus.className = 'closed';
      };

      }

      form.onsubmit = function(e) {
          e.preventDefault();

        // Retrieve the message from the textarea.
        var message = messageField.value;
        socket.send(message);
        messagesList.innerHTML += '<li class="sent"><span>Sent:</span>' + message +
                                  '</li>';

        // Clear out the message field.
        messageField.value = '';
        return false;
      };
javax.websocket.DeploymentException: The HTTP response from the server [400] did not permit the HTTP upgrade to WebSocket
    at org.apache.tomcat.websocket.WsWebSocketContainer.connectToServer(WsWebSocketContainer.java:343)
    at com.example.simplewebsocketserver.WebSocketClient.connecttoserver(WebSocketClient.java:101)
    at com.example.simplewebsocketserver.WebSocketController.getOperatorTokenDefinition(WebSocketController.java:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)