spring websocket http-status-code-403 sockjs

Spring WebSocket se conecta con SockJS a un dominio diferente



http-status-code-403 (4)

WebSockets en Spring es un tema bastante nuevo que me estoy cansando de encontrar un poco más.

Mi problema es con la conexión a un servicio de un dominio diferente, estoy trabajando con Lineman construyendo el lado frontal y Spring Boot cuando hago el lado posterior, con eso tengo estas aplicaciones en dos puertos diferentes: 8000 y 8080 en localhost.

Tuve problemas con el encabezado ''Access-Control-Allow-Origin'' pero lo resolví agregando un filtro en el lado del servidor que agregó el origen permitido al encabezado. Después de esto comencé a obtener el siguiente error en la conexión:

GET http://localhost:8080/socket/info 403 (Forbidden) AbstractXHRObject._start @ sockjs-0.3.4.js:807 (anonymous function) @sockjs-0.3.4.js:841

No tengo Spring Security en el proyecto, por lo que no es un problema de autorización, el error apunta a sockJS: that.xhr.send (payload); - donde la carga útil nunca se define. Intenté, pero no pude encontrar la raíz de la llamada, donde puede comenzar.

Estaba pensando si debo agregar alguna información adicional a SockJS y Stomp al configurar la conexión, pero no hay muchos ejemplos y notas en ambas páginas wiki de estas herramientas.

A continuación encontrarás el código de conexión JS.

var socket = new SockJS("http://localhost:8080/socket"); client = Stomp.over(socket); client.connect({''login'': BoatsGame.userName, ''passcode'': ''guest''}, function (frame) { .... The Server Side has a MessageBroker configured : @Configuration @EnableWebSocketMessageBroker public class MessageBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer { @Bean public ServletServerContainerFactoryBean createWebSocketContainer() { ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); container.setMaxTextMessageBufferSize(8192); container.setMaxBinaryMessageBufferSize(8192); return container; } @Override public void configureMessageBroker(MessageBrokerRegistry config) { //config.enableStompBrokerRelay("/queue", "/topic"); config.enableSimpleBroker("/queue", "/topic","/user"); config.setApplicationDestinationPrefixes("/BoatBattleGame"); } @Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint("/socket").withSockJS(); } }

También intenté configurar un MessageHandler ya que tiene la opción de configurar OriginAllowe al configurar, pero no estoy seguro de cómo está conectado al agente.

Por último piense, esta configuración funciona correctamente cuando se ejecuta en un puerto.


A cualquiera que llegue a este ticket debido a la respuesta prohibida 403 cuando intenta conectarse a través de un SockJsClient a un dominio diferente:

El problema surge cuando se trata de hacer un GET a la URL de / info, como parte del protocolo de enlace. La respuesta en realidad devuelve un 200 a través de WGET, así como a través del navegador. Sólo a través de SockJsClient no funciona.

Después de probar diferentes soluciones, la única que realmente solucionó el problema es escribir una clase que implemente Transporte e InfoReceiver. De esta manera el desarrollador puede manejar directamente esta parte del apretón de manos. Básicamente haces el trabajo en el método executeInfoRequest ():

@Override public String executeInfoRequest(URI infoUrl, HttpHeaders headers) { HttpGet getRequest = new HttpGet(infoUrl); // eventually add headers here HttpClient client = HttpClients.createDefault(); try { HttpResponse response = client.execute(getRequest); List<String> responseOutput = IOUtils.readLines(response.getEntity().getContent()); return responseOutput.get(0); } catch (IOException ioe) { ... } }

Definí TransportType.XHR como tipo de transporte.


Anwesr de Jax estaba en lo correcto :)

El método registerStompEndpoints nos da la oportunidad de establecer los orígenes permitidos. Necesitamos agregarlo antes de la opción "withSockJs ()".

@Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint("/BO/socket").setAllowedOrigins("*").withSockJS(); }


En mi caso, tuve que agregar estas configuraciones para que SockJS / STOM funcione con CORS:

@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowCredentials(false) .maxAge(3600) .allowedHeaders("Accept", "Content-Type", "Origin", "Authorization", "X-Auth-Token") .exposedHeaders("X-Auth-Token", "Authorization") .allowedMethods("POST", "GET", "DELETE", "PUT", "OPTIONS"); } }


Encontré esta solución creando un filtro

package com.diool.notif.config; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class SimpleCORSFilter implements Filter { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(SimpleCORSFilter.class); @Override public void init(FilterConfig filterConfig) throws ServletException { LOGGER.info("Initilisation du Middleware"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest requestToUse = (HttpServletRequest)servletRequest; HttpServletResponse responseToUse = (HttpServletResponse)servletResponse; responseToUse.setHeader("Access-Control-Allow-Origin",requestToUse.getHeader("Origin")); filterChain.doFilter(requestToUse,responseToUse); } @Override public void destroy() { } }