Habilitando solicitações de origem cruzada para WebSockets na primavera

Eu tenho um servidor OpenShift Wildfly. Estou construindo um site com oSpring MVC estrutura. Uma das minhas páginas da web também usa uma conexão WebSocket. No lado do servidor, usei o@ServerEndpoint anotação ejavax.websocket.* biblioteca para criar meu websocket:

package com.myapp.spring.web.controller;
import java.io.IOException;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.springframework.web.socket.server.standard.SpringConfigurator;


@ServerEndpoint(value="/serverendpoint", configurator = SpringConfigurator.class)

public class serverendpoint {

    @OnOpen
    public void handleOpen () {
        System.out.println("JAVA: Client is now connected...");
    }

    @OnMessage
    public String handleMessage (Session session, String message) throws IOException {

        if (message.equals("ping")) {
//            return "pong"
                session.getBasicRemote().sendText("pong");
        }
        else if (message.equals("close")) {
            handleClose();
            return null;
        }
        System.out.println("JAVA: Received from client: "+ message);
        MyClass mc = new MyClass(message);
        String res = mc.action();
        session.getBasicRemote().sendText(res);
        return res;
    }

    @OnClose
    public void handleClose() {
        System.out.println("JAVA: Client is now disconnected...");
    }

    @OnError
    public void handleError (Throwable t) {
        t.printStackTrace();
    }
}

O OpenShift fornece uma URL padrão, para que todas as minhas páginas da web (arquivos html) tenham o nome de host comum (canônico). Por uma questão de simplicidade, estou chamando este URLURL A (projectname-domainname.rhclound.com) Eu criei um alias, CNAME, deURL A, que é chamadoURL B (dizerhttps://www.mywebsite.tech)URL B é seguro, pois tem ohttps.

Estou usando um cliente JavaScript para conectar-se ao WebSocket no caminho/serverendpoint. O URI que estou usando no meu arquivo de página da web html,test.html, é o seguinte:

var wsUri = "wss://" + "projectname-domainname.rhclound.com" + ":8443" + "/serverendpoint";

Quando eu abroURL A (projectname-domainname.rhclound.com/test), o WebSocket se conecta e tudo funciona bem. No entanto, quando tento conectar-me ao soquete da Web usandoURL B (https://mywebsite.tech/test), o cliente JavaScript se conecta e desconecta imediatamente.

Aqui está a mensagem do console que eu recebo:

Aqui está o meu código JavaScript que se conecta ao WebSocket:

/****** BEGIN WEBSOCKET ******/
            var connectedToWebSocket = false;
            var responseMessage = '';
            var webSocket = null;
            function initWS() {
                connectedToWebSocket = false;
                var wsUri = "wss://" + "projectname-domainname.rhcloud.com" + ":8443" + "/serverendpoint";
                webSocket = new WebSocket(wsUri); // Create a new instance of WebSocket using usUri
                webSocket.onopen = function(message) {
                    processOpen(message);
                };
                webSocket.onmessage = function(message) {
                    responseMessage = message.data;
                    if (responseMessage !== "pong") { // Ping-pong messages to keep a persistent connection between server and client
                        processResponse(responseMessage);
                    }
                    return false;
                };
                webSocket.onclose = function(message) {
                    processClose(message);
                };
                webSocket.onerror = function(message) {
                    processError(message);
                };
                console.log("Exiting initWS()");
            }

            initWS(); //Connect to websocket

            function processOpen(message) {
                connectedToWebSocket = true;
                console.log("JS: Server Connected..."+message);
            }

            function sendMessage(toServer) { // Send message to server
                if (toServer != "close") {
                    webSocket.send(toServer);
                } else {
                    webSocket.close();
                }
            }

            function processClose(message) {
                connectedToWebSocket = false;
                console.log("JS: Client disconnected..."+message);
            }

            function processError(message) { 
                userInfo("An error occurred. Please contact for assistance", true, true);
            }
            setInterval(function() {
                if (connectedToWebSocket) {
                    webSocket.send("ping");
                }
            }, 4000); // Send ping-pong message to server
/****** END WEBSOCKET ******/

Depois de muita depuração e tentativa de várias coisas, concluí que esse problema estava ocorrendo devido ao Spring Framework.Isso ocorre porque antes de apresentar oSpring Framework no meu projeto,URL B poderia se conectar ao WebSocket, mas após a introdução do Spring, ele não pode.
Eu li sobresite da primavera sobre a política do WebSocket. Me deparei com elesmesma política de origem que afirma que um apelido,URL B, não pode se conectar ao WebSocket porque não é a mesma origem queURL A é. Para resolver este problema eudesativou a mesma política de origem com WebSockets como dito na documentação, então adicionei o seguinte código. Eu pensei que isso iria corrigir o meu erro. Aqui está o que eu adicionei:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer;

@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected boolean sameOriginDisabled() {
        return true;
    }

}

No entanto, como isso não resolveu o problema, adicionei o seguinte método ao meuApplicationConfig qualextends WebMvcConfigurerAdapter:

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**").allowedOrigins("https://www.mywebsite.com");
}

Isso também não funcionou. Então eu tentei isso:

package com.myapp.spring.security.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class MyCorsFilter {

//  @Bean
//  public FilterRegistrationBean corsFilter() {
//      System.out.println("Filchain");
//      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//      CorsConfiguration config = new CorsConfiguration();
//      config.setAllowCredentials(true);
//      config.addAllowedOrigin("https://www.mymt.tech");
//      config.addAllowedHeader("*");
//      config.addAllowedMethod("*");
//      source.registerCorsConfiguration("/**", config);
//      FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
//      bean.setOrder(0);
//      System.out.println("Filchain");
//      return bean;
//  }

     @Bean
     public CorsFilter corsFilter() {
         System.out.println("Filchain");
         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
         CorsConfiguration config = new CorsConfiguration();
         config.setAllowCredentials(true); // you USUALLY want this
         config.addAllowedOrigin("*");
         config.addAllowedHeader("*");
         config.addAllowedMethod("*");
         config.addAllowedMethod("*");
         source.registerCorsConfiguration("/**", config);
         System.out.println("Filchain");
         return new CorsFilter(source);
     }

}

Isso também não funcionou.

Eu até mudei ovar wsURI no código JS para o seguinte:var wsUri = "wss://" + "www.mywebsite.com" + ":8443" + "/serverendpoint"; Entãovar wsUri = "wss://" + "mywebsite.com" + ":8443" + "/serverendpoint";

Quando fiz isso, o Google Chrome me deu um erro, dizendo que o aperto de mão falhou. No entanto, quando eu tenho esse URL,var wsUri = "wss://" + "projectname-domianname.rhcloud.com" + ":8443" + "/serverendpoint";, Não recebi o erro de que o handshake não ocorreu, mas recebo uma mensagem informando que a conexão foi aberta e fechada imediatamente (como visto acima).

Então, como posso corrigir isso?

questionAnswers(1)

yourAnswerToTheQuestion